Pickaxe 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +9 -0
- data/bin/drill +4 -0
- data/bin/pickaxe +1 -61
- data/lib/pickaxe.rb +1 -1
- data/lib/pickaxe/cli.rb +53 -0
- data/lib/pickaxe/main.rb +12 -3
- data/lib/pickaxe/test.rb +26 -9
- metadata +8 -5
data/README.markdown
CHANGED
@@ -4,3 +4,12 @@ Pickaxe provides a simple way to load, solve and rate tests
|
|
4
4
|
(bundle of questions) written in simple text format.
|
5
5
|
|
6
6
|
Documentation can be read [here](http://dejw.github.com/pickaxe/).
|
7
|
+
|
8
|
+
**Note:** pickaxe was not tested on Windows yet (and it will not work there
|
9
|
+
since `Pickaxe::Shell` executes some terminal related code).
|
10
|
+
|
11
|
+
## instalation
|
12
|
+
|
13
|
+
sudo gem install Pickaxe
|
14
|
+
|
15
|
+
|
data/bin/drill
ADDED
data/bin/pickaxe
CHANGED
@@ -1,64 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'optparse'
|
4
|
-
|
5
2
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
6
|
-
|
7
3
|
require 'pickaxe'
|
8
|
-
|
9
|
-
# TODO:
|
10
|
-
# time limit
|
11
|
-
# syntax check only
|
12
|
-
# default -> warns + ignore, options for exception on syntax error ;-)
|
13
|
-
|
14
|
-
options = {}
|
15
|
-
OptionParser.new do |opts|
|
16
|
-
opts.banner = <<END_OF_BANNER
|
17
|
-
Usage:
|
18
|
-
pickaxe path [, path ...]
|
19
|
-
|
20
|
-
Uses given paths (files or directories) to generate a test from *.txt files.
|
21
|
-
END_OF_BANNER
|
22
|
-
|
23
|
-
opts.separator ""
|
24
|
-
opts.on("-e", "--ext [EXTENSION]", "Use files with given EXTENSION (default 'txt')") do |extension|
|
25
|
-
options[:extension] = extension
|
26
|
-
end
|
27
|
-
|
28
|
-
opts.on("-s", "--sorted", "Do not shuffle questions") do |v|
|
29
|
-
options[:sorted] = true
|
30
|
-
end
|
31
|
-
|
32
|
-
opts.on("--select [NUMBER]", "Select certain number of questions") do |v|
|
33
|
-
options[:select] = Integer(v)
|
34
|
-
end
|
35
|
-
|
36
|
-
opts.on("--full-test", "Checks test after all questions are answered") do |v|
|
37
|
-
options[:full_test] = true
|
38
|
-
end
|
39
|
-
|
40
|
-
opts.on("--strict", "Quit on syntax error in test file") do |v|
|
41
|
-
options[:strict] = true
|
42
|
-
end
|
43
|
-
|
44
|
-
opts.on_tail("--syntax-check", "Check syntax only - do not run test") do
|
45
|
-
options[:syntax_check] = true
|
46
|
-
end
|
47
|
-
|
48
|
-
opts.on_tail("--version", "Show version") do
|
49
|
-
puts "pickaxe version #{Pickaxe::VERSION}"
|
50
|
-
exit
|
51
|
-
end
|
52
|
-
|
53
|
-
opts.on_tail("-h", "--help", "Show this message") do
|
54
|
-
puts opts
|
55
|
-
exit
|
56
|
-
end
|
57
|
-
end.parse!
|
58
|
-
|
59
|
-
begin
|
60
|
-
Pickaxe::Main.new(ARGV, options)
|
61
|
-
rescue Pickaxe::PickaxeError => e
|
62
|
-
$stderr.puts(("! " + e.message).color(:red))
|
63
|
-
exit(e.status_code)
|
64
|
-
end
|
4
|
+
require "pickaxe/cli"
|
data/lib/pickaxe.rb
CHANGED
data/lib/pickaxe/cli.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
options = {}
|
4
|
+
OptionParser.new do |opts|
|
5
|
+
opts.banner = <<END_OF_BANNER
|
6
|
+
Usage:
|
7
|
+
#{$0.split("/").last} path [, path ...]
|
8
|
+
|
9
|
+
Uses given paths (files or directories) to generate a test from *.txt files.
|
10
|
+
END_OF_BANNER
|
11
|
+
|
12
|
+
opts.separator ""
|
13
|
+
opts.on("-e", "--ext [EXTENSION]", "Use files with given EXTENSION (default 'txt')") do |extension|
|
14
|
+
options[:extension] = extension
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("-s", "--sorted", "Do not shuffle questions") do |v|
|
18
|
+
options[:sorted] = true
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("--select [NUMBER]", "Select certain number of questions") do |v|
|
22
|
+
options[:select] = Integer(v)
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("--full-test", "Checks test after all questions are answered") do |v|
|
26
|
+
options[:full_test] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("--strict", "Quit on syntax error in test file") do |v|
|
30
|
+
options[:strict] = true
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on_tail("--syntax-check", "Check syntax only - do not run test") do
|
34
|
+
options[:syntax_check] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on_tail("--version", "Show version") do
|
38
|
+
puts "pickaxe version #{Pickaxe::VERSION}"
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
43
|
+
puts opts
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
end.parse!
|
47
|
+
|
48
|
+
begin
|
49
|
+
Pickaxe::Main.new(ARGV, options)
|
50
|
+
rescue Pickaxe::PickaxeError => e
|
51
|
+
$stderr.puts(("! " + e.message).color(:red))
|
52
|
+
exit(e.status_code)
|
53
|
+
end
|
data/lib/pickaxe/main.rb
CHANGED
@@ -18,6 +18,11 @@ END_OF_TEST
|
|
18
18
|
@test = Test.new(*paths)
|
19
19
|
return if options[:syntax_check]
|
20
20
|
|
21
|
+
puts "! Hit Control-D to end test.\n\n"
|
22
|
+
|
23
|
+
@logger = Logger.new(File.open('answers.log', File::WRONLY|File::TRUNC|File::CREAT))
|
24
|
+
@logger.formatter = lambda { |severity, time, progname, msg| msg.to_s + "\n" }
|
25
|
+
|
21
26
|
@questions = @test.shuffled_questions
|
22
27
|
@answers = Hash.new([])
|
23
28
|
@started_at = Time.now
|
@@ -74,7 +79,7 @@ END_OF_TEST
|
|
74
79
|
if Main.options[:full_test] and @question.nil?
|
75
80
|
Main.options[:full_test] = false
|
76
81
|
Main.options[:force_show_answers] = true
|
77
|
-
|
82
|
+
|
78
83
|
@current_index = 0
|
79
84
|
else
|
80
85
|
@current_index += 1
|
@@ -93,7 +98,7 @@ Available commands (whitespace does not matter):
|
|
93
98
|
END_OF_HELP
|
94
99
|
false
|
95
100
|
else
|
96
|
-
@answers[@question] = line.split(/\s+/).collect(&:strip)
|
101
|
+
@answers[@question] = line.strip.split(/\s+/).collect(&:strip)
|
97
102
|
puts @question.check?(@answers[@question]) unless Main.options[:full_test]
|
98
103
|
@current_index += 1
|
99
104
|
true
|
@@ -102,7 +107,11 @@ END_OF_HELP
|
|
102
107
|
|
103
108
|
def statistics!
|
104
109
|
@stats = @test.statistics!(@answers)
|
105
|
-
|
110
|
+
|
111
|
+
@answers.each do |question, answers|
|
112
|
+
@logger << ("#{question.index}: #{answers.join(" ")}\n")
|
113
|
+
end
|
114
|
+
|
106
115
|
puts
|
107
116
|
puts "Time: #{spent?}"
|
108
117
|
puts "All: #{@questions.length}"
|
data/lib/pickaxe/test.rb
CHANGED
@@ -5,6 +5,7 @@ module Pickaxe
|
|
5
5
|
class TestSyntaxError < PickaxeError; status_code(2) ; end
|
6
6
|
class MissingAnswers < TestSyntaxError; status_code(2) ; end
|
7
7
|
class BadAnswer < TestSyntaxError; status_code(3) ; end
|
8
|
+
class BadQuestion < TestSyntaxError; status_code(4) ; end
|
8
9
|
class NoCorrectAnswer < TestSyntaxError; status_code(3) ; end
|
9
10
|
|
10
11
|
class TestLine < String
|
@@ -34,7 +35,7 @@ module Pickaxe
|
|
34
35
|
include Enumerable
|
35
36
|
|
36
37
|
# Ruby-comments and C-comments
|
37
|
-
COMMENTS_RE =
|
38
|
+
COMMENTS_RE = /^\s*#.*|^\/\/.*/
|
38
39
|
|
39
40
|
def initialize(*files)
|
40
41
|
@files = files.collect do |file_or_directory|
|
@@ -44,7 +45,7 @@ module Pickaxe
|
|
44
45
|
else
|
45
46
|
Dir.glob("#{file_or_directory}/*.#{Main.options[:extension] || "txt"}")
|
46
47
|
end
|
47
|
-
end.flatten.collect(
|
48
|
+
end.flatten.collect { |f| f.squeeze('/') }
|
48
49
|
|
49
50
|
@questions = []
|
50
51
|
@files.each do |file|
|
@@ -108,7 +109,9 @@ module Pickaxe
|
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
111
|
-
class Question < Struct.new(:file, :content, :answers)
|
112
|
+
class Question < Struct.new(:file, :index, :content, :answers)
|
113
|
+
RE = /^\s*(\d+)\.?\s*(.+)$/
|
114
|
+
|
112
115
|
def self.parse(file, answers)
|
113
116
|
content = []
|
114
117
|
until answers.first.nil? or Answer::RE.match(answers.first)
|
@@ -116,10 +119,22 @@ module Pickaxe
|
|
116
119
|
end
|
117
120
|
|
118
121
|
raise MissingAnswers, "#{file}: line #{answers.first.index}: no content (check blank lines nearby)" if content.blank?
|
119
|
-
|
122
|
+
raise BadQuestion, "#{file}: line #{content.first.index}: '#{content.first.truncate(20)}' does not look like question" unless m = RE.match(content.first)
|
123
|
+
|
120
124
|
error_template = "#{file}: line #{content.first.index}: question '#{content.first.truncate(20)}' %s"
|
121
125
|
raise MissingAnswers, (error_template % "has no answers") if answers.blank?
|
122
|
-
|
126
|
+
|
127
|
+
answers = answers.inject([]) do |joined, line|
|
128
|
+
if Answer::RE.match(line)
|
129
|
+
joined << [line]
|
130
|
+
else
|
131
|
+
raise BadAnswer, "#{file}: line #{line.index}: '#{line.truncate(20)}' starts with weird characters" unless Answer::LINE_RE.match(line)
|
132
|
+
joined.last << line
|
133
|
+
end
|
134
|
+
joined
|
135
|
+
end
|
136
|
+
|
137
|
+
Question.new(file, m[1], content, answers.collect {|answer| Answer.parse(file, answer) }).tap do |q|
|
123
138
|
raise NoCorrectAnswer, (error_template % "has no correct answer") if q.correct_answers.blank?
|
124
139
|
end
|
125
140
|
end
|
@@ -160,10 +175,12 @@ module Pickaxe
|
|
160
175
|
end
|
161
176
|
|
162
177
|
class Answer < Struct.new(:content, :index, :correctness)
|
163
|
-
RE = /^\s*(>>)
|
164
|
-
|
165
|
-
|
166
|
-
|
178
|
+
RE = /^\s*(>>)?\s*(\?\?)?\s*\((\w+)\)\s*(.+)$/
|
179
|
+
LINE_RE = /^\s*(\w+)/
|
180
|
+
|
181
|
+
def self.parse(file, lines)
|
182
|
+
m = RE.match(lines.shift)
|
183
|
+
Answer.new(m[m.size-1].strip + " " + lines.collect(&:strip).join(" "), m[m.size-2].strip, m[1] == ">>")
|
167
184
|
end
|
168
185
|
|
169
186
|
def to_s
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Pickaxe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 2
|
10
|
+
version: 0.4.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dawid Fatyga
|
@@ -15,8 +15,8 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
19
|
-
default_executable:
|
18
|
+
date: 2010-12-01 00:00:00 +01:00
|
19
|
+
default_executable: bin/pickaxe
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -73,6 +73,7 @@ description: |
|
|
73
73
|
email: dawid.fatyga@gmail.com
|
74
74
|
executables:
|
75
75
|
- pickaxe
|
76
|
+
- drill
|
76
77
|
extensions: []
|
77
78
|
|
78
79
|
extra_rdoc_files:
|
@@ -82,10 +83,12 @@ extra_rdoc_files:
|
|
82
83
|
files:
|
83
84
|
- lib/pickaxe.rb
|
84
85
|
- lib/pickaxe/test.rb
|
86
|
+
- lib/pickaxe/cli.rb
|
85
87
|
- lib/pickaxe/color.rb
|
86
88
|
- lib/pickaxe/extensions.rb
|
87
89
|
- lib/pickaxe/shell.rb
|
88
90
|
- lib/pickaxe/main.rb
|
91
|
+
- bin/drill
|
89
92
|
- bin/pickaxe
|
90
93
|
- README.markdown
|
91
94
|
- Gemfile
|