電波ビーチ

☆(ゝω・)v

rubyの便利コマンドラインパーサoptparseのdescriptionがsummaryなので見やすくしたい

なにをいってるかわからねータイトルですが。

rubyにはoptparseっていうコマンドラインパーサが標準ライブラリ*1があり、使う機会があった

github.com

-hでヘルプを表示できるのだが、たとえばこんなやつ

require "optparse"

OptionParser.new do |opt|
  begin
      # バージョンを追加
      opt.version = "0.0.1"
      # リリース日を追加
      opt.release = "2018-11-12"
      # 名前を追加
      opt.program_name = ""
      # Usageで最初に表示されるやつ
      opt.banner = "Usage: #{opt.program_name} [options] [directory]"
      # helpとかUsageで表示されるときのサマリーが始まるまでの行頭からの幅
      summary_width = 32
      opt.summary_width = summary_width
      # 同じくコマンドのインデント
      summary_indent = 4
      opt.summary_indent = ' ' * summary_indent
      # summaryの幅を改行時にも揃えたい。長文で折り返した際も同じようにインデントするようにしたい
      # opt.onでオプションとそのdescを追加
      opt.on("-x", "所詮サマリーなのでそもそも長文を書くものではないんだけど、それにしてもターミナル幅が短いとめちゃくちゃ読みにくいしつらい。\n改行なんてしようもんならもっとひどいことになる。とても読めたものではない"){ |v|
          options[:a] = v
      }
      opt.separator("")
      opt.on("-h", "--help", "show help."){
          puts opt.help
          exit
      }
      opt.on("-v", "--version", "show version."){
          puts opt.ver
          exit
      }
      opt.parse!(ARGV)
  rescue OptionParser::InvalidOption => e
      puts e.message
      return
  end
end

を、ヘルプオプションで表示しようとすると、ターミナル幅が70とかだとこんな感じになっちゃう f:id:or3:20181112101242p:plain

これがストレスなのでちゃんとインデント付きで折り返してくれるようなヘルパー関数を作ってあげた

github.com

(中見ればわかりますが力ずくでよろしくやっているだけ...)

*1:rubyの文化知らんのだが組み込みgem?でいいのかな

【AOJ】Rubyで2次元配列を連番で初期化 && Rubyでpythonのisdigitっぽいやつ

AOJ ITP1_6_B

タイトルのやつでおいしい書き方ができずに少しハマった。

2次元配列を連番で初期化

map内での宣言で要素を初期化できる。範囲オブジェクトをto_aで配列にしてぶちこんだ。

cards = Array.new(4).map { Array.new((1..13).to_a) }
=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]]

isdigitっぽいやつ

pythonだとよくある感じの書き方で、文字列のリストの要素の中で数値に変換できるやつは変換してしまう、というやつはisnumericを使う。

target = list(map(lambda a: int(a) if a.isnumeric() else a, input().split()))

べつにisdigitでもいいんだけど、なんかのやつでなぜか漢数字を変換しなくちゃいけない場面があって以来isnumeric万能ってなったので使っている。

kk6.hateblo.jp

Rubyにはそんな便利なメソッドは無いらしい。調べると正規表現でやっているのをよく見かけるので真似した。

konbu13.hatenablog.com

こちらのをパクらせていただきました。ありがとうございます。

今回はfloatにも対応するようにしてみた。三項演算子入れ子にしたのだが、いちいちmatchを判断しているところが冗長で遅そう。正規表現力が圧倒的に足りない。

arr = ["unk0", "321", "0.00220", "y00011", "321.32xx334" "127.0.0.1"]
arr.map { |t| t.match? (/^\d+\.?\d+$/) ? (t.match? (/\./) ? t.to_f : t.to_i) : t }
=> ["unk0", 321, 0.0022, "y00011", "321.32xx334", "127.0.0.1"]

mkdirで連番ディレクトリの作成

あらすじ

直近のABC1071完だった。酒が入っていた&&出先で適当に暇つぶしのつもりだった&&時間が30分ほどしかなかったとはいえ、半年ほどろくにコードを書いてないだけでこれほどカスに成り果ててしまった。とてもかなしいのでAOJ Introduction fungosを始めようと思う。今作った造語だが、AOJ Introduction to Programmingをただやるだけである。

これだけ

で、やろうと思って、とりあえず環境を作った。ITP1はITP1_1からITP1_18まで、各AからDまでの問題がある。それらをディレクトリごとで分ける。プロジェクトルートで

mkdir -p ITP1/ITP1_{1..18}{A..D}

これで環境は整った。今日から毎日やっていく。

Rubyでの開発で最近学習したこと Rspec

or3.hatenablog.com

のシリーズの続きのつもりです。

  • 環境
  • 基礎
    • 「とりあえず写経/コピペするだけだし'test'ってフォルダ/ファイル/class/メソッド名でいいや。そういうのgithubでよく見るし」
    • TDD?
    • BDD?
    • spec?
  • プロジェクトフォルダ作成
  • bundlerでRSpecをインストール
    • bundle init
    • bundle install --path vendor/bundle
    • 以降はexecをつけて実行
  • rspecの初期化
  • テストコードを書く
  • テストしてみる
  • 参考
続きを読む

Rubyでの開発について最近学習したこと rbenv, gem, rubygems, bundler

最近っつっても一月くらい前に書いて以降ほったらかしにしてたやつです。長いので目次付きです。
自分用のメモ代わりに書いてたもので、いちおうわりと知識がなくても頭からおっていけば忘れてからでも分かるように丁寧に書いたつもりですが、文体とか構成とか基礎知識がおかしいところには目をつむってくだしあ

  • Ruby開発環境やツールの学習
    • rbenv
    • gem
    • Rubygems
      • gemを使ってみる
        • グローバルにrubyを入れる
        • プロジェクト作る
        • プロジェクトルート直下に(ローカルの)rubyを入れる
        • 入ってるgem一覧 gem list
        • 入ってないやつをインストール/更新/削除してみる
      • gemでrailsを探して入れるまで
        • gem search
        • gem install
        • gem update
        • gem uninstall
      • このままだとグローバルなrbenvにgem installされてしまう
    • Bundler
      • Bundler 参考
      • Bundlerを入れる
        • 【rbenv rehashについて】
      • 初期化
      • Gemfile
      • いれてみる
      • なんだこいつら
      • bundle exec
      • せっかくなのでrailsを入れて動かしてみる
  • 続き
続きを読む

scdlでLikeしたプレイリストをとってくる(こともできる)

ふつうにscdl -l https://soundcloud.com/userID -fとかやると、Likeしたプレイリストはとれず、なぜか先頭の曲だけ落ちるんですが、soundcloud APIの仕様ぽいので諦めてました。

or3.hatenablog.com

自分のアカウントからは/setsで見れるので、各プレイリストのidをスクレイピングで取得してscdlに投げる方法を以前やったのですが、他人のアカウントでは使えませんでした。

stackoverflow.com

ところがこちらの記事によれば、公開はされていないAPIを利用することで可能とのこと。

'playlist_likes': ('https://api.soundcloud.com/e1/users/{0}/playlist_likes?limit=5'),

これをソースのAPIのURLのdictに追加して、

elif dl_type == 'playlist_likes':
    download_playlist(item['playlist'])

みたいにすれば確かに任意のユーザのLikeのうちプレイリストのみDLすることができました。ただし、めっちゃ頻繁に503になってしまうので、limitパラメータとtime.sleepで余裕をもたせています。