読者です 読者をやめる 読者になる 読者になる

基本的に怠Diary

学習ログを残したい

野球よくわからないけどとりあえずオリックス応援することにした。

野球 Ruby

死ぬほどどうでもいいですがリポジトリいろいろ整理しました。

後アカウント2つあったんですが一つにしてさらにもういじらないリポジトリ消しました。

これからはコードとか公開して後悔するいく必要があると思い、

せめて完成までいけそうなコードだけ公開することにしました。

以上


それでね、情報とかいろいろ見るんだけど

いちいちサイト見に行って調べるのめんどくせえなあとか思ったりするわけですよ。

なんか情報とか手っ取り早く確認できるサイトねーかなー

???「ないならお前が作れ」

というわけで作ります。

Webスクレイピングで野球データを取りまくる。

今回のデータ取得にあたり、正直マナー違反かもしれないと思った。

一応一ページ一秒は守っていたし特にrobot.txtとか見つからなかったのでスクレイピングさせていただいだけど

12球団の全選手の個別のページ見に行って過去の簡易データ取りに行ってました。

次にWebスクレイピングやるときは最小のページ数で済むように構成するのが課題ですね。

# coding: utf-8


require 'open-uri'
require 'nokogiri'
require 'fileutils'
require 'active_record'

ActiveRecord::Base.establish_connection(
  "adapter" =>"sqlite3",
  "database" => "./baseball.db"
)
#この雑なまとめ方
class Fielder_score < ActiveRecord::Base
end
class Player < ActiveRecord::Base
end
class Pitcher_score  < ActiveRecord::Base
end

#選手のページからデータを取得
def insertPlayerData(uri,playerName,id,type)
  doc = getDoc(uri)
  doc.xpath('//div[@id="3yrsstat"]').each do |node|
    node.css("tr.yjM").each do |n|
      row = n.css("td").map(&:inner_text).compact.reject(&:empty?)
      #職人が一つ一つ手で入力しました。
      if type === "p"
        Pitcher_score.create(:p_id => id,
                             :year => row[0],
                             :term_name => row[1],
                             :defense_rate => row[2],
                             :game_number => row[3],
                             :win => row[4],
                             :lose => row[5],
                             :hold_save => row[6],
                             :pitching_time => row[7],
                             :hit => row[8],
                             :homerun => row[9],
                             :strikeout => row[10],
                             :four => row[11],
                             :dead => row[12],
                             :point => row[13])
      else
        Fielder_score.create(:p_id => id,
                             :year => row[0],
                             :term_name => row[1],
                             :batting_rate => row[2],
                             :game_number => row[3],
                             :stroke_cnt => row[4],
                             :hit => row[5],
                             :homerun => row[6],
                             :hit_point => row[7],
                             :score => row[8],
                             :struck_out => row[9],
                             :four => row[10],
                             :dead => row[11],
                             :sacrifice => row[12],
                             :sacrifice_fly => row[13],
                             :steal_base => row[14])
      end
    end
  end
  #サーバへの瞬間的負荷の軽減
  sleep(1)
end
#ドキュメント取得
def getDoc(uri)
  begin
  charset = nil
  html = open(uri) do |f|
    charset = f.charset
    f.read
  end
  rescue  => exception
    case exception
    when OpenURI::HTTPError
      puts "ページが見つかりません。#{uri}"
    when URI::InvalidURIError
      puts "URLが入力されていません。"
    else
      puts exception.to_s + "(#{exception.class})"
    end
    return nil
  end
  return Nokogiri::HTML.parse(html, nil, charset)
end

def player_get(type,term_num)
  baseUri = "https://baseball.yahoo.co.jp"
  uri = baseUri + "/npb/teams/#{term_num}/memberlist?type=#{type}"

  playerUri = []
  doc = getDoc(uri)
  team_name = doc.xpath('//title').first.inner_text.split("-")[1]
  position = type === "p"? "投手" : "野手"
  #投手の一覧を取得
  p_id = 0
  doc.xpath('//td/a').each do |node|
    playerUri.push(baseUri + node.attribute('href').value)
    reco = Player.find_by(:name => node.inner_text)
    if !reco
      Player.create(:name => node.inner_text,:current_team => team_name,:position => position)
      reco = Player.find_by(:name => node.inner_text)
    end
    p_id = reco[:p_id]
    insertPlayerData(baseUri + node.attribute('href').value,node.inner_text,p_id,type)
  end
end
#すべてのチームの選手の年度別の情報を取得する
def all_team_player_year_score
  #ここまでいびつなアレならいっそ特定ページからリンクを拾うようにしてもいいかも
  term_nums = [1,2,3,4,5,6,7,8,9,11,12,376]
  start_time = Time.now
  term_nums.each do |i|
    ["p","b"].map do |type|
      player_get(type,i)
      p "球団#{i}: #{Time.now - start_time}s"
    end
  end
  p "終了 #{Time.now - start_time}s"
end
all_team_player_year_score

DBにいれるとこが一番気に食わない。

ちなみに最終的にScalaJavaScriptで書き直す予定です。

Ruby好きだけどRailsはなんか使いたくないイキってる雑魚オタクです。

最近Reactを少々勉強しているのでそれ使いたい。

けど動かないことには始まらないのでとりあえずコマンドラインツールをRubyで実装してからその後のことは考えます。

なのでRailsになったり、sinatraになるかもしれません。

師匠が欲しい(届かぬ思い

追記

やらかした。term_nameってなんだよ。。。

機能追加中に気がついた。辛い。

Riotjs入門したらコケた ~動作確認~

だから追いかけた。

qiita.com

とりあえずこの記事見て進めることに。

環境はVagrant上のCentOS7

npmは4.0.5

nodeは7.4.0

とりあえずこの記事ではbabelとbuble?を利用する2通りが存在するみたいで

私はbubleわからないのでbabelを選択。babelも対して理解してないけどね。

とりあえず要求通りにインスコし、ディレクトリ構成もしっかりと確認し、

コードもまず動くことが第一なのでコピペして入れて、npm run build

動かない。しかし今回はとっても優しいエラー文だった。

TypeError: _webpack2.default.optimize.OccurenceOrderPlugin is not a function

そんな関数ねーよ!ってことですねなるほどなるほどTypoかな?とりあえずぐぐる

そうすると以下のような記事を発見

github.com

そして下に進んでいくと

OccurenceOrderPlugin has been renamed to OccurrenceOrderPlugin.

英語わからないけど名前変わってOccurrenceOrderPluginになったよって書いてある。

なんかr増えてる。誰かがTypoしてるの見つけてそれを最近になって修正したってことかな。

まあとにかく動かしましょう。

すると再びエラー。まあこの程度で音を上げるようではnpmと付き合うのは不可能。

しかし今度のエラーは難しい。一部を取り出して検索してみる

(とりあえずconfiguration[0].module has an unknown property ‘preLoaders'をGoogleに放り込む)

すると

github.com

オッ

npm uninstall webpack --save-dev
npm install webpack@2.1.0-beta.22 --save-dev

これで・・・!

npmの仰々しいエラーはなくなったが、どうやらriot周りでエラーこいてる感じ。

普通に確認してみたらなんのこともない

app/app.jsのとこのパス指定が多分間違ってる。

require(‘../app.tag’);

ここ、ディレクトリ構成確認するとわかるけど

../tag/app.tag

なんだよね。

./ ├ .gitignore ├ node_modules ├ package.json ├ webpack.config.js ├ index.html ├ app │ └ app.js ←こいつが │ ├ tag │ └ app.tag ←こいつを読み込まないといけないので │ └ build └ bundle.js

そんなこんなで今度こそrun buildしたら無事記事の通り動作しました。

基本的にRiotjsの記事厳しいのばかりでしたがこの記事が一番優しく感じました。

対処も簡単だったしね。


動いたのはいいんだけどなんで動いてるのか一ミリもわからねえ。

恐らくriotではなくwebpackが理解できていない。

まあ2.1.0でいいかなという感想だけど恐らく今後使い続けてるとwebpack周りで死にそうだし

やっぱ調べとくか。気が向いたらやる()

死ぬ前にやれることはすべてやろう

自殺を考えてる人へ

自殺をする前にやれることはすべてやろう。

これは生きるためでもあり、この世から未練を消すための活動でもあります。

何をするかって、何でもいいです。流石に人に迷惑かけるのはやめましょうとかは言わない。

復讐したいんならすればいいです。人を幸せにしたいんならそれでもいいです。

やりたいことをやりましょう。そしてやりたいことができた後、もしくはやろうとした後

また、やりたいことを考えて実行を繰り返してください。

多分それ繰り返してると最後に玉が尽きて死ねますよ。

なんてドヤ顔で言ってみたけど、これって別に新しいことでもなんでもないですね。

まあ何故こんなことをこんなとこに発言したのかというと

言い訳です。

この先、私はなりふり構わずに行きますよっていう儀式です。私は追い詰められたら

自己厨うんこ発言放出してストレスを開放しています。

もし、それで生き残ることができたなら、次に何事もなく私は恥と新しい記事を書きます(なんちて

これは儀式。私はいつも失敗ばかりで、迷惑をたくさんかけて、死ねばいいと自分で勝手に攻め続けて(周りは口にしない)

攻めて攻めて攻めて攻めて攻めて攻めて攻めて

死にそうになります。

私にとって常識は重すぎる。SNSで馬鹿かこいつwwwwwみたいなツイートが回ってくると

RTして文句言いつつも、いつか私も職場の使えないやつとして紹介されるかもしれないなどと

考えたりします。

私はクズです。どうしようもないクズです。

実際悩んでいることの9割は普通の人なら大したことないことで、

相談したらお前自己厨だなむしろお前が悪いから直したほうがいいよとアドバイスしていただけることだと思います。

私はそんな世界で生きているどうしようもない生物です。可能なら殺処分してください。

私は死にたくないし、苦しいのは嫌ですから。

こんなカス活かすくらいなら

自殺する人間の中で世間一般的に良い人間と評価される方を救うようにしたほうがいいです。

私みたいな人間が他人に迷惑をかける。そして人間様に迷惑をかける。そして社会をダメにする。

そう考えていくと人間として生きるのが辛くなる。

だから私はやめました。もっと迷惑かけてやる。自分に優しく生きてやる。

お前らなんぞ知ったことか、何人死のうが知ったことか。これが俺の本性だ。

迷惑だと思うなら殺してください人間様。おねがいします。

抵抗するので寝てる間に殺処分してください。

ScalaでKuromoji使う

Scala Kuromoji

イミュータブルには勝てなかったよ・・・

RSS取得してからTitleとDescription別で3文字以上の単語が何個でたか集計してくれる大したことないやつ

var使ったら負けだと思ってたけど普通に負けた。

package TextMining

import java.net.URL

import org.atilika.kuromoji._

import scala.collection.mutable
import scala.xml.{NodeSeq, XML}

class AnalRSS(u:String) {
  val baseXML = XML.load(new URL(u))
  val items = (baseXML \\ "item")
  def saveXML(filepath:String): Unit ={
    XML.save(filepath,baseXML,"UTF-8",true,null)
  }
  def analStr(target:String):Seq[(String,Int)] = {
    val tokenizer = Tokenizer.builder().build().tokenize(target)
    var wordMap = mutable.TreeMap.empty[String,Int]
    tokenizer.stream()
      .filter(x => x.getSurfaceForm.length > 3)
      .forEach({x =>
        if(!wordMap.contains(x.getSurfaceForm))
          wordMap(x.getSurfaceForm) = 1
        else
          wordMap(x.getSurfaceForm) += 1
      })
    return wordMap.toSeq
  }
  def getRSSSelfTag(items:NodeSeq = this.items,tagName:String): List[(String,Int)] ={
    var allWords = List.empty[(String,Int)]
    items.foreach(x=>analStr((x \\ tagName).text).foreach(y =>{
      val removeFind = allWords.find(z=>z._1==y._1)
      if(removeFind != None)
        allWords = allWords.filterNot(z=>z._1==y._1) :+ (y._1,y._2 + removeFind.get._2)
      else
        allWords = allWords :+ y
    }))
    return allWords
  }
  def getRSSTitleAndDesc(url:String = u,items:NodeSeq = this.items): (List[(String,Int)],List[(String,Int)] ) = {
    return (getRSSSelfTag(items,"title"),getRSSSelfTag(items,"description"))
  }
}

ひどい名前(2つの意味で

フィルタは結局かけなかった。まだその域ではない。

これJarファイルとかにしてcronあたりで回してデータ集めるのもよかったけど

なんかもういいやってなったのでやめた。今はWordPressに集中したい。

わけねーだろすぐにやめても大学やめてRailから外れてRails始めるやつの二の舞いじゃボケ。

以上Scalaの練習第一弾でした。

Scala全然わからないので特にやりたいことないからCop見ながら探します。

さっき投稿したやつでも書きましたが、小ネタとかローカルブログ(笑)に蓄積していつか放流します。

Goも再開したいし、Rubyもやりたいのん。

国家試験あるけど受けないかもしれない。Twitterアカウントなくても困らないしな。

当分はEmacsとWordPress(PHPはわからない)がメインです。

Rubyは悲しいけど休憩かな(´・ω・`)

WordPressに移行します!!!

やっぱすげーよ公開してるブロガーは

私はローカルに立ててメモ代わりみたいに利用しつつ遊びます。

粒度が小さいのである程度溜まって、ちょっと加工してからこっちに放出しようと思う。

本当はそういうのQiitaとかが最適なんだろうけど

被ってんじゃねえかとかこれ間違ってますよ死ねとか言われたら多分いまの精神状態的に死にます。

ほんとよわい 鰯かよ

人生辛い。何が辛いかって、この辛さ人々に伝えたらその程度とかお前が悪いとかしか帰ってこないところ。

さらにさらに私自身それで納得してしまうこと。

そうだよ悪いの私だよ悪いの私だよ。

私が救われる方法は一つ。誰にも文句言われなくなるほど優秀になるか

死ぬか。

ScalaでJUnit事始めと見せかけて実は大したことできないからとりあえず初めてだから許してって気持ちかなり入ってる

趣味プログラミング Scala JUnit

仕事が辛い。無能すぎて辛い。

上司とか上司がすごく苦い顔してくるのかなり辛い。

能力は非常に高いです。私を雇う以外は特に失敗は確認できません。

人を見る目以外はとてもすごい上司です。尊敬してます。

ごめんなさいごめんなさいごめんなさい

それはさておきScalaする。

Scalaは一年ぐらいかけてのんびりやりたいのでテストとか書いて丁寧にやりたい。

いやそれが当たり前なんだけどね。

というわけでテストフレームワークを使うのは確定で、

何を使うのかと言うとタイトル通りJUnitを使って行きたいと思います。

JUnitなら仕事で使う可能性の高いJavaとかにも活かせるしいいかなーって

JUnitの技術書買ったし、

記事書くっつったし

ちなみに開発環境はZorinOSでIntelliJ Idea使ってますです。

ビルドツールはsbt使ってます。IntelliJの設定でPlugin追加してあげました。

当たり前ですがプロジェクト作成時点でJUnitなんて入ってないので

sbtの場合はインスコしてあげることを教えてあげないといけないです。

>libraryDependencies += "com.novocode" % "junit-interface" % "0.8" % "test->default"

ちなみにこの一行はぐぐって見つけたものをそのままいれてbuild moduleさせたらなんかインスコしてくれました(問題発言

alvinalexander.com

それは流石にダメだから調べてみる。

sbt Reference Manual — ライブラリ依存性

なんか公式っぽいとこにあった。

libraryDependencies += groupID % artifactID % revision

でも最後のtest->defaultってなんなのだろう

ある依存ライブラリが Test コンフィギュレーションのクラスパスには出てきてほしいが、 Compile コンフィギュレーションでは要らないという場合は、以下のように % "test" と追加する:

defaultってなんだよってば

sbt Reference Manual — Library Management

めっちゃ探した・・・・もうマヂムリ・・・

libraryDependencies += "org.scalatest" %% "scalatest" % "2.1.3" % "test->compile"

似たようなのあった

This says that your project’s "test" configuration uses ScalaTest’s "compile" configuration. See the Ivy >documentation for more advanced mappings. Most projects published to Maven repositories will use the >"compile" configuration.

Google翻訳大先輩

これは、プロジェクトの「テスト」設定がScalaTestの「コンパイル」設定を
使用していることを示しています。
より高度なマッピングについては、Ivy>のドキュメントを参照してください。
 Mavenリポジトリに公開されるほとんどのプロジェクトは、 "コンパイル"設定を使用します。

つまり「test」設定がJUnitの「default」設定を使用しているということか*1

なるほど、微妙にわからん。


クラスとかはCopの本にあるクラスを使ってテストします。

RationalTest.scala

import org.junit.{Test,Assert}
import chap6.Rational


class RationalTest {
  @Test
  def toStringTest = {
    val n = 5
    val d = 1
    val rat = new Rational(n,d)
    Assert.assertEquals(rat.toString,"created " + n + "/" + d)
  }
  @Test(expected = classOf[IllegalArgumentException])
  def zeroCheckTest = {
    val rat = new Rational(5,0)
  }
}

Assert.assertEqualsの使い方はまんまだったけど

例外投げる挙動のテストだとJavaと微妙に違ったので

かなり調べて思いつかなかったけどIntelliJくんがこれじゃねって教えてくれてなんとかできた。

@Test(expected = classOf[IllegalArgumentException])

ここなんだけど、私が見ていたJavaの技術書ではIllegalArgumentException.class

でいけるって書いてあったけどどうやらScalaではclassOfでクラスを取得するようだ。

あ、ちなみにRationalクラスはまだ途中だけどこんな感じ

class Rational(n:Int,d:Int) {
  require(d != 0)
  override def toString = "created " + n + "/" + d
}

これからもテスト頑張るぞい。

もとい、Scala一年続けることのできるように

この後滅茶滅茶参考にした。 Amazon CAPTCHA

*1:私の英語力は底辺中学生レベルです。

宇宙(そら)へ・・・

Emacs Spacemacs

f:id:saborin78:20170112192756p:plain

スペェェェスゥェエェェィィムァァァックス(ねっとりボイス

私のEmacsが宇宙でカスタムされたSpacemacsになりました。

明日をつかめデビルマシン♪

とりあえず.emacs.dをすり替えて再び起動したらSpacemacsになってました。

でも使い方ってなんか変わるのでしょうか。

と触って初めて気がつく。

Vimってる!?

どういうことだってばよ・・・とりあえずEmacsすごい人達の作った記事を見ることに

qiita.com

Spacemacsとはemacsの便利機能を設定の手間を最小限に、提供するemacs lisp群である

なるほど。

だが使い方はわからん。

とりあえずRubyやらJSやらの補完とか欲しいのでホームディレクトリの下にできているという.spacemacsの

dotspacemacs-configuration-layersに言語を追加してEmacs再び立ち上げると

なんか更新始まりました。

どうやら自動でインストールしてくれるみたいです。

まぁいろいろあるんですけどね、

すごく使いづらいというか使い方わかってないのがあれ

C-x uでUndoするときによくわからない画面が立ち上がって謎の動きするの辛い。

ここでもうやめるってなるのがぱしょこんしょしんしゃ

ぼくは初学者だ。冷静に画面の情報を集めるところから始めることができる。

するとundo-treeという名前が書いてあるではないか。なぜ知らないと言われても

私はキーバインドになれてからそういうの入れようと思ってたんです。決して

undo-treeくんを忘れてたわけではないんです。

とりあえず彼と理解するところから始めましょう。

qiita.com

(今回リンク多すぎでは)

ブログはじめたてというか最近までリンクって極力少なくしたほうがいい的なことついったランドの

意識とプログラミング力の高い人間たちを見て私もそれに当てられてましたが

よくよく考えてみるとリンク集でも十分だよなって思いました。

〜言い訳タイム終了〜

ようするにGitだねって問題発言。実用Gitで詳しく説明してくれてるけど私は全然わかってない。

ただこれ使い方が悪いのか、画面をどんどん奪っていくのほんとつらい。

でもUndo一気に戻れるの便利だから使ったちゃう///

そしてポエム書いてたら何も進まずに今日は終わりへと向かっていく。

今日の進捗。

f:id:saborin78:20170112224504j:plain

ブログ書いてる途中で何やってんだ俺ってなりました。