長い文字を「...」で省略する方法(Ruby・Rails・JavaScript)

【結論】

・文字を省略したい場合、Railsであれば、truncateメソッドを利用する方法がある

Rubyであれば、範囲オブジェクトで文字の範囲を指定して、表示をさせる事

JavaScriptの場合は、slice() メソッドで文字の省略が可能

【目次】

【本題】

文字数を省略させたいケース

無制限に文字が表示されてしまうと、レイアウトが崩れてしまうので、表示させる文字数を制限したい事が多々あります。

そういった場合に、利用出来る手法をいくつか紹介します。

Railsの場合(truncateメソッド)

Railsの場合、truncateというメソッドで、表示させる文字サイズを指定する事が可能です。

#()内に表示したい文字数を指定
str = "abcdefg"
str.truncate(6)
=> "abc..."
#()内に表示したい文字数を指定
str = "abcdefg"
truncate(str, length: 6)
=> "abc..."

http://railsdoc.com/references/truncate

Rubyの場合(範囲オブジェクト)

Rubyの場合、範囲オブジェクトで文字数を指定する事が可能です。

#[]内に表示したい文字数を指定
str = "abcdefg"
str[3]
=> "abc"

JavaScriptの場合(slice メソッド)

JavaScriptの場合、sliceというメソッドで、表示させる文字サイズを指定する事が可能です。

#()内に表示したい文字の範囲を指定
str = "abcdefg"
str.slice(0,2)
=> "abc"

String.prototype.slice() - JavaScript | MDN

参考情報

Rails - 長い文字列を省略して表示する - Qiita

【JavaScript】長い文章の文末を省略して末尾に「…」を表示させる方法 – 株式会社シーポイントラボ | 浜松のシステム・RTK-GNSS開発

【AtCoder:3回目】AtCoder Beginner Contest 128の振り返り(Ruby)

【目次】

【本題】

振り返り

今回は、5/26(日)に開催されたAtCoder Beginner Contest 128の振り返りを行います。

AtCoder Beginner Contest 128 - AtCoder

結果は、2問目で力尽きて、3問目に到達できず・・・

ratingは微増です

色が付くのは、まだ先ですね・・・

A - Ferris Wheel

問題文 林檎が A 個、林檎の欠片が P 個あります。

林檎 1 個は、砕くことで林檎の欠片 3 個になります。また、林檎の欠片 2 個を鍋で煮込むことで、アップルパイが 1 個作れます。

今ある材料で作れるアップルパイの最大数を求めてください。

りんごは全部欠片にして、欠片を足して、2で割るだけと考えました。

a,piyo=gets.split.map &:to_i
 
p ( ( a * 3 ) + piyo ) / 2

他の回答を見ても、概ね同じ方法でした。

B - Guidebook

問題文 あなたは美味しいレストランを紹介する本を書くことにしました。 あなたは N 個のレストラン、レストラン 1 、レストラン 2 、 … 、レストラン N を紹介しようとしています。レストラン i は S i 市にあり、あなたは 100 点満点中 P i 点と評価しています。 異なる 2 個のレストランに同じ点数がついていることはありません。

この本では、次のような順でレストランを紹介しようとしています。

市名が辞書順で早いものから紹介していく。 同じ市に複数レストランがある場合は、点数が高いものから紹介していく。 この本で紹介される順にレストランの番号を出力してください。

今回は、下記の様な手順で処理する方法を考えました。

1:標準入力を配列に格納 2:1の配列から、Nを抜き出す 3:Nを抜き取った配列の各要素に並び順で連番を割り振る 4:3を市名で昇順にソートする 5:4から市名だけ抜き出し、重複を排除した配列を作成する 6:5をeachで回して、その中で同じ市名のグループを抽出し、点数でソートする 7:6をeachで回して、3で割り振った連番を、配列の並び順に出力する

inputs = []
while input = $stdin.gets do
  inputs << input.chomp.split(" ")
end
 
n = inputs.shift
citys = []
 
inputs.each.with_index(1) do |city, i|
  city << i
  citys << city
end
 
citys_name_sort = citys.sort
 
super_citys = []
names = []
 
citys_name_sort.each do |name|
  names << name[0]
end
 
names.uniq.each do |name|
  check_names = []
  citys_name_sort.each do |city_n|
    if name == city_n[0]
      check_names << city_n
    end
  end
  super_citys << check_names.sort{ |a, b| b[1].to_i <=> a[1].to_i }
end
 
super_citys.each do |a0|
  a0.each do |a1|
    p a1[2]
  end
end

4の時点で、点数も含めてソートされると思ったのですが、上手くいかなかったので、5〜6の処理を追加しました。

思いつきの力技なので、かなりグチャグチャです・・・

そして他の人の回答を見ていると、下記でもいける様でした。

N = gets.to_i
 
list = []
N.times do |i|
  s, p = gets.split(" ")
  p = p.to_i
  list << [s, -p, i+1]
end
 
list.sort!
list.each do |(a, b, i)|
  puts i
end

「なんでソート一回で上手く行ってるの?」

府に落ちなかったので、出力結果を見比べました。

#自身のコード
[["khabarovsk", "20", 1], ["moscow", "10", 2], ["kazan", "50", 3], ["kazan", "35", 4], ["moscow", "60", 5], ["khabarovsk", "40", 6]]

#模範コード
[["khabarovsk", -20, 1], ["moscow", -10, 2], ["kazan", -50, 3], ["kazan", -35, 4], ["moscow", -60, 5], ["khabarovsk", -40, 6]]

「あっ(察し)」

模範はint型にして、かつ負号を付ける事で、昇順でソートさせる事ができる様でした。

めっちゃ簡単な問題だったんですね・・・

【AtCoder:2回目】AtCoder Beginner Contest 127の振り返り(Ruby)

【目次】

【本題】

振り返り

今回は、5/26(土)に開催されたAtCoder Beginner Contest 127の振り返りを行います。

AtCoder Beginner Contest 127 - AtCoder

結果は、2問しか解けないという事で、見事に撃沈しています・・・

なお、前回参加したコンテストはUnratedだったので、今回初めてratingが付きました!

5回参加するまでは、大幅に低く見積もられるそうです。 いずれにしても、水色にはほど遠い・・・

A - Ferris Wheel

問題文 A 歳の高橋君が観覧車に乗ろうとしています。

この観覧車は、 13 歳以上が乗るには B 円 ( B は偶数) かかりますが、 6 歳以上 12 歳以下の人はその半額で乗ることができ、 さらに 5 歳以下の人は無料で乗ることができます。

高橋君が観覧車に乗るには何円かかるかを求めてください。

0〜5が無料で、6〜12が半額、それ以外は通常価格という条件式を組めば良いと考えました。

私の回答はこちらです。

a,b=gets.split.map &:to_i

case a
  when 0..5
    p 0
  when 6..12
    p b / 2
  else
    p b
end

今回はcase文で解きましたが、caseだと比較演算子が使えなかったので、範囲オブジェクトで数値を表しています。

ちなみに、IF文だとこんな感じでしょうか。

a,b=gets.split.map &:to_i

if a <= 5
  p 0
elsif a <= 12
  p b/2
else
  p b
end

B - Algae

問題文 ある池に生えている藻類は、以下のように成長します。

西暦 i 年になる瞬間に生えている重さの合計を x i グラムとすると、 i ≥ 2000 に対して、以下の式が成り立ちます:

x i + 1

= r x i − D r , D , x 2000 が与えられます。 x 2001 , ..., x 2010 を計算し、順に出力してください。

10回繰り返しで処理を回して、一番初めは「r * x - d」で計算し、その後は値を更新しながら計算と出力を繰り返していく方法を考えました。

その回答がこちらです。

r,d,x=gets.split.map &:to_i

 before_reef = 0

10.times do
  if before_reef == 0
    reef = r * x - d
  else
    reef = r * before_reef - d
  end
  p reef
  before_reef = reef
end

ただ他の回答などを見ると、もっとシンプルに解ける方法がありました。

r,d,x=gets.split.map &:to_i

10.times do
  p x = r * x - d
end

いちいち別の変数に定義し直す必要無いやん・・・

C - Prison

問題文 N 枚の ID カードと M 個のゲートがあります。

i 番目のゲートは L i , L i + 1 , . . . , R i 番目の ID カードのうちどれか 1 枚を持っていれば通過できます。

1 枚だけで全てのゲートを通過できる ID カードは何枚あるでしょうか。

各L〜Rの範囲の値の最小公約数が答えるなると考えて回答した内容が下記です。

sss = []
while bbb = $stdin.gets do
  sss << bbb.chomp.split(" ")
end

l = 0
r = 100000

sss.delete_at(0)

sss.each do |s|
  l = s[0].to_i if s[0].to_i > l
  r = s[1].to_i if s[1].to_i < r
end

p r - l + 1

こちらサンプルは通りましたが、いくつかのテストケースでエラーになってしまいました。

これを解消させたコードがこちらです。

N,M=gets.split.map &:to_i
l=0
r=100000
M.times{
    a,b=gets.split.map &:to_i
    l = a if l < a
    r = b if r > b
}
puts [r-l+1, 0].max

qmk_firmwareでキーマップを変更する

【結論】

・自作キーボードは、キーマップを自由に設定できるのが大きな特徴

・キーマップを設定するには、qmk_firmwareを利用する

・qmk_firmwareに任意のキーマップを記述して、書き込む事で設定が完了する

【目次】

【本題】

自作キーボードのキーマップ

先日、自作キーボードを制作しましたが、初期のキーマップは若干MacBookと異なり、使いづらい部分がありました。

なので、キーマップを書き換えることにしたので、その過程で調べた事をまとめます。

↓過去記事

ryoutaku-jo.hatenablog.com

ryoutaku-jo.hatenablog.com

qmk_firmwareの導入

まずは、キーマップを設定する為のqmk_firmwareを導入します。

qmk_firmwareGItHubからcloneしてきます。

$ git clone https://github.com/qmk/qmk_firmware
$ cd qmk_firmware

そして、下記コマンドでビルド環境を整えます。

$ ./util/qmk_install.sh

デフォルトのキーマップをコピー

私が制作したキーボード(Mint60)のデフォルトのキーマップの設定が記述されたファイルは、下記の階層に保存されています。

qmk_firmware
 - keyboards
  - mint60
   - keymaps
    - default

そちらを土台にキーマップをカスタマイズして行くので、ファイルをコピーします。

なお、ファイル名は「custom」としています。

$ cp -r keyboards/mint60/keymaps/default keyboards/mint60/keymaps/custom

キーマップをカスタマイズ

コピーしたファイルを開きます。

キーマップに関する記述は下記のコードになります。

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [0] = LAYOUT( \
    KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,      KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,    KC_BSPC,  \
    KC_TAB,    KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,      KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,  \
    KC_CAPS,     KC_A,    KC_S,    KC_D,    KC_F,    KC_G,      KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,        KC_ENT,   \
    KC_LSFT,       KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,      KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,   KC_UP,  MO(1),   \
    KC_ESC,    KC_LCTL,    KC_LGUI,    KC_LALT,    KC_SPC,        KC_BSPC, KC_ENT,  LALT(KC_GRV),               KC_LEFT,KC_DOWN,KC_RGHT \
  ),
  [1] = LAYOUT( \
    KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,     KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,    KC_DEL, \
    RGB_TOG,   RGBRST,  RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
    XXXXXXX,     RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,        XXXXXXX, \
    _______,       XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_PGUP, _______, \
    XXXXXXX,   _______,    _______,    _______,    XXXXXXX,       XXXXXXX, XXXXXXX, XXXXXXX,                   KC_HOME, KC_PGDN, KC_END \
  )
};

これは実際にキー配列と同じ内容になっています。

[0]の内容がベースで、「MO(1)」に対応するキーを押す事で、[1]のキーが反応する様になっています。

それぞれのコードがどのキーに対応するかは、下記から確認できます。

qmk_firmware/docs/keycodes_basic.md at master · qmk/qmk_firmware · GitHub

今回はあまり凝った内容にしない様に、下記の様に変更しました。

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [0] = LAYOUT( \
    KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,   KC_5,        KC_6,    KC_7,    KC_8,     KC_9,    KC_0,      KC_MINUS, KC_EQUAL, KC_BSPC,         \
    KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,   KC_T,        KC_Y,    KC_U,    KC_I,     KC_O,    KC_P,      KC_RBRC,  KC_BSLS,  KC_NONUS_BSLASH, \
    KC_CAPS, KC_A,    KC_S,    KC_D,    KC_F,   KC_G,        KC_H,    KC_J,    KC_K,     KC_L,    KC_SCOLON, KC_QUOTE, KC_ENT,                    \
    KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,   KC_B,        KC_N,    KC_M,    KC_COMMA, KC_DOT,  KC_SLASH,  KC_ESC,   KC_UP,    KC_SLCK,           \
    MO(1),   KC_LCTL, KC_LALT, KC_LGUI, KC_SPC,              KC_SPC,                     KC_RGUI, KC_RALT,   KC_RSFT,  KC_DOWN,  KC_RGHT          \
  ),
  [1] = LAYOUT( \
    KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,      KC_F6,   KC_F7,   KC_F8,    KC_F9,   KC_F10,    KC_F11,   KC_F12,   KC_DEL,  \
    RGB_TOG, RGBRST,  RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX,    XXXXXXX, XXXXXXX, XXXXXXX,  XXXXXXX, XXXXXXX,   XXXXXXX,  XXXXXXX,  XXXXXXX, \
    XXXXXXX, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX,    XXXXXXX, XXXXXXX, XXXXXXX,  XXXXXXX, XXXXXXX,   XXXXXXX,  XXXXXXX,           \
    _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,    XXXXXXX, XXXXXXX, XXXXXXX,  XXXXXXX, XXXXXXX,   _______,  KC_PGUP,  _______, \
    XXXXXXX, _______, _______, _______, XXXXXXX,             XXXXXXX,                    XXXXXXX, XXXXXXX,   KC_HOME,  KC_PGDN,  KC_END   \
  )
};

あとは、これをキーボードに書き込みます。

make mint60:custom:avrdude

これで設定完了です。

参考情報

GitHub - qmk/qmk_firmware: Open-source keyboard firmware for Atmel AVR and Arm USB families

http://www.urong-answer.org/2018/08/changed-keymap-for-mint60/

seed-fuでシードファイルをもっと便利に

【結論】

Railsにはrake db:seedで初期データを投入する方法が標準で備わっている

・しかし、環境毎に内容を分けたり、一度作成したデータは投入しない様にしたりといった細かい調整が面倒

seed-fuというgemを用いれば、それらの設定を簡単に行える

【目次】

【本題】

初期データの管理について

Railsにはrake db:seedで初期データを投入する方法が標準で備わっています。

しかし、下記の様に、細かく設定を行おうとすると、少し不便です。

  • 環境ごとにデータの内容を変える

  • 既に作成されたデータは再投入しない様にする

  • デプロイと一緒に初期データを投入したい

そんな時に役立つのがseed-fuです。

これは、シードファイルの管理を容易に行う為のgemです。

導入方法

まずはgem本体をインストールします。

gem 'seed-fu'

環境毎に読み込むシードファイルを分ける

次にdb/fixturesディレクトリ配下にseedファイルを作成します。

この際、developmentproductionというディレクトリを作成して、そこにseedファイルを格納すると、環境毎に読み込むseedファイルを切り替える事が可能です。

データの更新したく無い場合

一度初期データを作成した後に、再読み込みしたく無い場合は、seed_onceを利用します

Point.seed_once(:x, :y) do |s|
  s.x = 4
  s.y = 7
  s.name = "Home"
end

Capistranoの自動デプロイと一緒に読み込む

config/deploy.rbに下記を記述すれば、Capistranoで本番環境にデプロイした時に、同時に初期データを投入する事も可能です。

require 'seed-fu/capistrano'

# Trigger the task after update_code
after 'deploy:update_code', 'db:seed_fu'

参考情報

GitHub - mbleigh/seed-fu: Advanced seed data handling for Rails, combining the best practices of several methods together.

seed-fu を使い、Rails上で使うデータを設定する話 - Qiita

railsで初期データを入れる(seed-fuの使い方) - Qiita

Railsでseed-fuを使って初期データを作ろう! - bagelee(ベーグリー)

[Rails] seed-fu を使って初期データを作成する | DevelopersIO

seed-fuで始める効率的なRails Seed管理【Rails 4 x Ruby 2.1】 | 酒と涙とRubyとRailsと

【AtCoder:1回目】AtCoder Beginner Contest 126の振り返り(Ruby)

【結論】

Rubyで回答しています。

・ABCしか解けなかったので、振り返りはその3問のみです。

・解説ではなく、自身の振り返りです(クソコードしか書いてない・・・)

【目次】

【本題】

AtCoder Beginner Contest 126の振り返り

初めてAtCoderのコンテストに挑戦したので、その振り返しをしたいと思います。

今回挑戦したのは、5/19(日)に開催された「AtCoder Beginner Contest 126」です。

AtCoder Beginner Contest 126 - AtCoder

結果

6問中、3問しか解けませんでした・・・

それに、デバック用に記述していたputsを消し忘れて「不正解」になる等、凡ミスも多発しました・・・

それでも、初めてにしては上出来だと前向きに捉えています!

A - Changing a Character

では、1問目から振り返ります。

問題文 A, B, C からなる長さ N の文字列 S と、1 以上 N 以下の整数 K が与えられます。 文字列 S の K 文字目を小文字に書き換え、新しくでき S を出力してください。

こちらに対する回答が以下の通りです。

N,K = gets.chomp.split(" ").map(&:to_i);
S = gets.chomp
 
result = []
 
S.chars.each_with_index do |str, index|
  if index == K - 1
    result << str.downcase
  else
    result << str
  end
end
 
puts "#{result.join}"

IF文で該当の文字列を特定し、小文字に置き換えるという処理です。

でも、他の方々の回答を見ていると、もっと良いやり方がありました。

n,k=gets.split.map &:to_i
s=gets
s[k-1]=s[k-1].downcase
puts s

文字列って、配列みたいな方法で文字を指定して取得出来るんですね💦

これで、いちいちIF文で、対象の文字列を特定しなくても、小文字に変換できるので、非常にスマートになりました!

B - YYMM or MMYY

問題文 長さ 4 の数字列 S が与えられます。あなたは、この数字列が以下のフォーマットのどちらであるか気になっています。

YYMM フォーマット: 西暦年の下 2 桁と、月を 2 桁で表したもの (例えば 1 月なら 01) をこの順に並べたもの MMYY フォーマット: 月を 2 桁で表したもの (例えば 1 月なら 01) と、西暦年の下 2 桁をこの順に並べたもの 与えられた数字列のフォーマットとして考えられるものが YYMM フォーマットのみである場合 YYMM を、 MMYY フォーマットのみである場合 MMYY を、 YYMM フォーマット と MMYY フォーマットのどちらの可能性もある場合 AMBIGUOUS を、 どちらの可能性もない場合 NA を出力してください。

私の回答はこちらです。

S = gets.to_s

int = S.scan(/.{1,#{2}}/)
 
if int[0].to_i.between?(1, 12) & int[1].to_i.between?(1, 12)
  puts 'AMBIGUOUS'
elsif !int[0].to_i.between?(1, 12) & !int[1].to_i.between?(1, 12)
  puts 'NA'
elsif !int[0].to_i.between?(1, 12) & int[1].to_i.between?(1, 12)
  puts 'YYMM'
else
  puts 'MMYY'
end

与えられるのは数字列という事でに関しては何も考慮せず、数字列の前方・後方の2桁がにあてはまるか?、つまり01〜12の間にあてはまるのか?だけ見れば良いと考えました。

まず、両方がMMか?否か?を判定した後に、片方づつMMか?判定する様にしています。

他の方の回答を見ると、case文で書かれていたり、正規表現を使ったり、三項演算子を用いてワンライナーで書いている人も居たりしました💦

中でも面白かったのは、下記の様にして、数字列の前方・後方の2桁を分割されているコードでした。

n = gets.to_i
a = n/100
b = n%100

例えば、入力値が「1990」の場合を想定します。

100(整数:integer型)で割ると、小数部分は切り捨てられるので、前方の「19」が得られます。

次に、100での剰余を求めると、後方の「90」が得られます。

これにより前方・後方の2桁を得る事が出来ます。

それを元に、初めのコードを組み替えると、下記の様になります。

S = gets.to_s

a = S/100
b = S%100
 
if a.between?(1, 12) & b.between?(1, 12)
  puts 'AMBIGUOUS'
elsif !a.between?(1, 12) & !b.between?(1, 12)
  puts 'NA'
elsif !a.between?(1, 12) & b.between?(1, 12)
  puts 'YYMM'
else
  puts 'MMYY'
end

先ほどよりスマートになりました。条件式部分もかなり改善の余地がありますが、長くなるので飛ばします。

C - Dice and Coin

問題文 すぬけ君は 1 〜 N の整数が等確率で出る N 面サイコロと表と裏が等確率で出るコインを持っています。すぬけ君は、このサイコロとコインを使って今から次のようなゲームをします。

まず、サイコロを 1 回振り、出た目を現在の得点とする。 得点が 1 以上 K − 1 以下である限り、すぬけ君はコインを振り続ける。表が出たら得点は 2 倍になり、裏が出たら得点は 0 になる。 得点が 0 になった、もしくは K 以上になった時点でゲームが終了する。このとき、得点が K 以上である場合すぬけ君の勝ち、 0 である場合すぬけ君の負けである。 N と K が与えられるので、このゲームですぬけ君が勝つ確率を求めてください。

私の回答がこちらです。

N,K = gets.chomp.split(" ").map(&:to_i);
 
win = []
 
N.times do |n|
  count = 0
  score = n + 1
  while score <= K - 1  do
    score *= 2
    count += 1
  end
  if count == 0
    win << N
  else
    win <<  2**count * N
  end
end
 
win_win = 0.to_f
 
win.each do |num|
  win_win += ( 1 / num.to_f )
end
 
puts win_win

変数名はテキトウです・・・

まず、サイコロの面の数だけ繰り返し処理をする様にtimesを記述します。

次に、勝利に必要なコイントスの回数を計算します。

最後は、コイントスの回数だけ2を累乗して、それにNを掛けます。

こうする事で、そのサイコロの目における勝利確率の分母が出せます(なお、コイントスする前に勝利が確定している場合は、サイコロの目だけを分母とします)

そして、それらの分母で1を割って、計算結果を全て合計すれば、確率が出せます(超ゴリ押し・・・)

他の方の回答で面白かったのは、reduce・Math・log2などを駆使して、解かれていた回答でした(どれも使った事が無い・・・)

https://ref.xaio.jp/ruby/classes/enumerable/reduce

module Math (Ruby 3.2 リファレンスマニュアル)

Math.#log2 (Ruby 3.2 リファレンスマニュアル)

改善点

  • 標準入力を取得する部分など、テンプレート化できる箇所は、テンプレを利用する

  • コードテストしてから提出する(存在を知らなかった)

  • putsとかデバック用に書いた記述の消し忘れ注意

  • リファレンスを読もう!!(知らないメソッドが一杯!!)

自作キーボードに入門した「2日目:完成!!」

【結論】

・前回の記事の続き

・自作キーボード初心者には、はんだ付けが一番の関門

・ミスするリスクもあるが、物作りの楽しさを味わえるのが、既製品には無い良さ!

【目次】

【本題】

前回までのあらすじ

肩凝り解消策の一環で、分離キーボードを作る事にしたが、思いの外、時間が掛かっている・・・

ryoutaku-jo.hatenablog.com

キースイッチが反応しない・・・

前回、キースイッチをはんだ付けするところまで行ったので、実際に接続して反応するか試して見ました。

しかし、キーが一切反応しません・・・

どうやらキー配列を設定書き込む処理が必要らしいようで、下記の手順で反応するようになりました。

http://www.urong-answer.org/2018/08/changed-keymap-for-mint60/

いよいよ完成!

LEDで光る仕様になっているので、LEDを取り付けて行きます。

これで基盤にはんだ付けするものは全て取り付けたので、土台となるアクリル板を取り付けて行きます。

そして、最後にキーキャップを取り付けて、これで完成です!!

(キーキャップの配列は一部テキトウです)

躓いたポイント(改善点)

* はんだ付けの練習をしておいた方が良い

私は正常に動きましたが、やっぱりぶっつけ本番で初心者がはんだ付けを試みるのは危険!

せめて、YouTubeとかで予習しておいた方が良いと思います。

* 動作チェックは細かく実施しよう

キースイッチを取り付けて、動作確認が取れる状態になったら、次に手順に進む前に、必ず動作確認をした方が良いでしょう。また、それ以降の工程においても、細かくチェックした方が良いでしょう。

私の場合、アクリル板を取り付ける前は正常に動作していたので、そのまま最後まで作業を進めてしまい、完成してから動作しなくなっている事に気づいて手戻りが発生しました・・・

* LEDとはんだが引っ付くと、動作不良を起こす

Mint60の場合、LEDテープ裏面の保護シールを剥がしてしまうと、金属面とキースイッチのはんだが接触して、キーが反応しなくなります(実際になった・・・)

下記の様に絶縁テープを貼って対処しました。

* はんだをつける場合は、適した部品なのか、しっかり確認する

この説明書きを見落として、はんだすべきで無いところに、はんだ付けしちゃいました・・・

ちゃんと説明書きは読みましょう

* ネジサイズを確認する

ネジサイズが違う事に途中まで気づかず、ネジが足りなくなってから気づいて、手戻りが発生したりしました・・・

* アクリル板は折れやすい

これは、一緒に作業していた、めっちゃ強そうな自作キーボード経験者の方から聞いた話ですが、「Mint60」のアクリル板は、それほど厚く無いので、力のさじ加減を間違えると、簡単に折れてしまう事が多いようです。

接着剤などで修復する事も可能でしょうが、不恰好になるので、細心の注意を払って取り扱った方が良いでしょう。

掛かった費用

  • Mint60キット= 15,984円

  • Tai-Hao PBT Hawaii(キーキャップのセット)= 8,100円

  • Gateron Silent 赤軸(66個×75円)= 4,950円

  • TRRSケーブル:324円

→合計:29,358円

「あれ?・・・普通に買った方が安くね?・・・」

〜終わり〜

自作キーボードに入門した「1日目:迷走中・・・」

【結論】

・自作キーボードとは、既製品では不可能なキー配列やデザインを実現させる為のキーボード

・変態的な(褒め言葉)自作キーボードを製作されている方も多くいらっしゃる(所謂、沼)

・既製品もあるので、作るのが面倒な人は、そちらをチョイスする方が合理的かもしれないが・・・そんなのロマンがねぇよ!

【目次】

【本題】

きっかけ:なんか無性に肩が凝る・・・

エンジニアとして転職して以降、これまで以上にずっとPCに向き合う機会が増えたせいか、肩こりが気になる様になりました。

ストレッチなどを定期的に行っても解消されず、何か良い方法は無いものかと模索していたところ、「分離キーボード」の存在を知りました。

「分離キーボード」とは、文字通り、キーボードが分かれた構成になっているものです(下記画像参照)

画像引用元 ロープロ仕様に生まれ変わった、MISTEL「MD650L」を試す。超小型な分離キーボードの新境地 - エルミタージュ秋葉原

通常のキーボードだと、体の前にキーボードを配置して、それに向かって腕を伸ばす体勢になるので、肩が丸まり、猫背になり易いです。

対して、分離キーボードだと、体の左右にキーボードを配置して、腕を大きく広げて作業が行えるので、猫背になりにくい特徴があります。

どこまで効果があるかは分かりませんが、ものは試しという事で、早速分離キーボードを探す事にしました。

自作キーボードの世界

分離キーボードは、その特殊な形状ゆえ、市販されているものは非常に少なく、高価でした。

そんな中、目に付いたのが、「自作キーボード」でした。

「自作キーボード」とは、自身でキーボードを組み立てる事で、市販の既製品には無い様なオリジナルのカスタマイズが施せる代物です。

なので、市販ではラインナップが少ない分離キーボードも、自作キーボードだと数多くのキットが販売されています。

とはいえ、自作でも色々揃えると既製品並みの金額になるし、失敗した時のリスクを考えると、大人しく既製品を買ったほうが良いとも感じました・・・

そんな尻込みしている時、会社の同期に何気なくキーボードの話を振ると、実は自作キーボード使いである事が判明しました!!

そして、様々なアドバイス(洗脳)を受ける過程で、「やっぱり時代は自作キーボードだ!」と確信し、休みの期間を利用して、製作に挑戦する事にしました!

製作環境と選んだキーボード

製作をするにあたり、会社の同期に勧めで、下記のショップに赴きました。

yushakobo.jp

こちらは最近オープンしたばかりの日本では数少ない自作キーボード専門店です。

工房も併設されており、何も器材を持っていない私には打ってつけでした。

こちらの店員さんに相談しながら、色々探した結果、下記のキーボードを選ぶ事にしました。

https://eucalyn.shop/shop/kits/mint60-startereucalyn.shop

選んだ理由は、下記の通りです。

  • 初心者でも簡単に組めるという評判(これが一番)

  • キー配列が、あまり凝った構成ではないので、慣れるのに苦労しなさす

  • 色づかいが女性ウケしそう(錯覚)

作業内容

組み立てにあたっては、下記のサイトを参考にしました。

Mint60の組み立て手順 - ゆかりメモ

とりあえず全部揃っているか確認。

そしてダイオードをぶっ刺して行きます。

次が、はんだ付けです・・・

これが一番の難関です

はんだ付けなんて、中学校の図工の時間以来、触った事がありません・・・

(しかも、机の穴にはんだを流し込んで遊ぶ事しかしなかったので、本格的な使い方は一切知らない・・・)

という事でYouTubeのはんだ職人の動画を見ながら、我流でテキトウ(誤用の方)に、はんだを付けて行きました!

これで大丈夫なんだろうか・・・

そうこうして、隣で作業していためちゃ強そうな自作キーボード使いの人のアドバイスも受けながら、作業を進める事・・・「4時間!!」

完成しねぇ・・・

誰だよ、初心者でも簡単とか言ったやつ・・・

こちとら日帰りでいけるくらいの甘い見通しで作業してるんだふざけるんじゃないよ全く!

そんな訳で、明日に続きます(これ本当に動く様になるのか・・・?)

グラフを簡単に描画する「Chart.js」について

【結論】

・Chart.jsを利用する事で、簡単にグラフ表示の機能を実装する事ができる

CDNなどでライブラリを読み込み、ページにスクリプトを埋め込んで、グラフ描画する場所にcanvas要素を記述する事で実装できる

スクリプトで定義している項目や値を、コントローラーから渡す事で、動的にグラフを生成する事が可能

【目次】

【本題】

グラフ機能を簡易に実装できる「Chart.js」について

「Chart.js」とは、JavaScriptで動作するシンプルかつモダンなグラフを簡単に実装できるライブラリです。

Chart.js | Open source HTML5 Charts for your website

公式サイトに掲載されていますが、下記の様なグラフを実装する事ができます。

Chart.js | Samples

実装手順1:本体のインストールする

実装の方法ですが、まずは本体をインストールする必要があります。

CDNでも配信されており、Railsであれば、下記の様にして読み込む事も可能です。

<%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js' %>

実装手順2:スクリプトを埋め込む

次にページに、どの様にグラフを描画するのかをスクリプトに定義して、埋め込みます。

公式サイトだと、下記のコードが掲載されていました。

<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ["赤", "青", "黄色", "緑", "紫", "橙"],
        datasets: [{
            label: '得票数',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255,99,132,1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});
</script>

実装手順3:グラフを描画する位置にcanvas要素を記述する

最後にグラフを描画する位置にcanvas要素を記述します。

<canvas id="myChart" width="400" height="400"></canvas>

これにより、実装されたグラフが下記になります。

スクリプトで定義している項目や値などをコントローラーで取得したデータに置き換えれば、動的にグラフを生成する事が可能です。

参考情報

Chart.js · Chart.js 日本語ドキュメント

RubyMineで毎回自動生成される.ideaについて

【結論】

・RubyMineで毎回自動生成される.ideaは、チーム間でプロジェクト設定を共有する為のファイル

・但し、チーム全員がRubyMineを共通設定で使用しないのであれば、GitHubに上げると邪魔になる

・毎回Gitの監視下に入るのが面倒であれば、gitignore_globalに登録すれば、都度gitignoreに登録する手間が省ける

【目次】

【本題】

RubyMineを使用していると生成される.idea

RubyMineを使っていると、.ideaという謎のファイルが、勝手に生成されてGitの監視下に加わります。 今回は、これが何か調べました。

チーム間で設定内容を共有するもの

下記の公式サイトによると、以下の様な説明でした。

Projects | IntelliJ IDEA Documentation

Project formats # In IntelliJ IDEA, there are two types of formats in which a project's configuration can be stored — the file-based format format (legacy) and the directory-based format (default and recommended).

For file-based projects, the IDE creates the .ipr, .iws and .iml files. For projects stored in the directory-based format, the IDE creates the.iml file and the .idea directory that keeps project settings.

どうやらプロジェクト設定を保存して、共有する為の物の様です。

全員がRubyMineを使用する訳ではない

同じ環境で開発を行えるという利点がある様ですが、エディタが違えば意味がありません。

不要なファイルがアップロードされていると、コードレビューの邪魔にもなりますので、特に利用していないのであれば、Gitの監視下から外しておくのが得策でしょう。

毎回gitignoreに登録するのは面倒

この.ideaは、毎回勝手に生成されますが、都度gitignoreに登録するのが面倒です。 また、他のメンバーに関係ないファイルがgitignoreに登録されているのも綺麗ではありません。

そういった個人の都合で毎回Gitの監視下から外したいのであれば、.gitignore_globalに登録するのが有用でしょう。

gitignore_globalは、全てのプロジェクトにおいて、登録したファイルをGitの監視下から外してくれます。

.gitignore_globalの設定方法

まず、下記のコマンドで.gitignore_globalを読み込む設定を行います。

git config --global core.excludesfile ~/.gitignore_global

次にホームディレクトリへ.gitignore_globalの作成と編集を行います。

$ vim ~/.gitignore_global

今回は、下記二種類のファイルを記述しました。

.idea/
.DS_Store

保存後、上記二つのファイルはGitの監視下から外れます。

参考情報

Projects | IntelliJ IDEA Documentation

https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems

グローバルに.gitignoreを設定する方法 | vdeep