timequiz 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/timequiz +26 -0
- data/doc/html/timequiz.html +515 -0
- data/doc/license.txt +674 -0
- data/doc/man/timequiz.6.gz +0 -0
- data/doc/pdf/timequiz.pdf +0 -0
- data/doc/rst/timequiz.rst +156 -0
- data/lib/adder.rb +74 -0
- data/lib/argparser.rb +85 -0
- data/lib/busy_indicator.rb +104 -0
- data/lib/color_output.rb +73 -0
- data/lib/console.rb +219 -0
- data/lib/constants.rb +41 -0
- data/lib/event.rb +41 -0
- data/lib/events.rb +45 -0
- data/lib/extstring.rb +161 -0
- data/lib/file_checking.rb +89 -0
- data/lib/logging.rb +204 -0
- data/lib/timequiz.rb +216 -0
- data/lib/user_input.rb +246 -0
- metadata +63 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
/***************************************************************************
|
4
|
+
* ©2011-2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
|
5
|
+
* *
|
6
|
+
* This program is free software; you can redistribute it and/or modify *
|
7
|
+
* it under the terms of the GNU General Public License as published by *
|
8
|
+
* the Free Software Foundation; either version 3 of the License, or *
|
9
|
+
* (at your option) any later version. *
|
10
|
+
* *
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
14
|
+
* GNU General Public License for more details. *
|
15
|
+
* *
|
16
|
+
* You should have received a copy of the GNU General Public License *
|
17
|
+
* along with this program; if not, write to the *
|
18
|
+
* Free Software Foundation, Inc., *
|
19
|
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
20
|
+
***************************************************************************/
|
21
|
+
=end
|
22
|
+
|
23
|
+
=begin
|
24
|
+
A module to facilitate frequently occuring checks on
|
25
|
+
file-system objects. You can certainly do without this,
|
26
|
+
but maybe you find it useful.
|
27
|
+
=end
|
28
|
+
module File_Checking
|
29
|
+
|
30
|
+
@@text_messages = {
|
31
|
+
:exist? => "does not exist!",
|
32
|
+
:exist => "does not exist!",
|
33
|
+
:readable? => "is not readable!",
|
34
|
+
:readable => "is not readable!",
|
35
|
+
:executable? => "is not executable!",
|
36
|
+
:executable => "is not executable!",
|
37
|
+
:writable? => "is not writable!",
|
38
|
+
:writable => "is not writable!",
|
39
|
+
:directory? => "is not a directory!",
|
40
|
+
:directory => "is not a directory!",
|
41
|
+
:file? => "is not a file!",
|
42
|
+
:file => "is not a file!",
|
43
|
+
}
|
44
|
+
|
45
|
+
# Checks if the file with the name from the first
|
46
|
+
# parameter has the properties, listed in the second.
|
47
|
+
# The messages parameter is an array of one or several
|
48
|
+
# of :exist?, :readable?, :writable?, :directory? or
|
49
|
+
# their string-representations, respectively.
|
50
|
+
# Returns nil in case of success, otherwise an
|
51
|
+
# informative message, describing the first negative
|
52
|
+
# test-result.
|
53
|
+
def file_check(file, *messages)
|
54
|
+
File_Checking.file_check(file, *messages)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Checks if the file with the name from the first
|
58
|
+
# parameter has the properties, listed in the second.
|
59
|
+
# The messages parameter is an array of one or all
|
60
|
+
# of :exist?, :readable?, :writable?, :directory? or
|
61
|
+
# their string-representations, respectively.
|
62
|
+
# Returns nil in case of success, otherwise an
|
63
|
+
# informative message, describing the first negative
|
64
|
+
# test-result.
|
65
|
+
def self.file_check(file, *messages)
|
66
|
+
msg = nil
|
67
|
+
if(file && messages.respond_to?(:to_ary) && !messages.empty?)
|
68
|
+
messages.each do |k|
|
69
|
+
if(! k.to_s.end_with?('?'))
|
70
|
+
k = (k.to_s << '?').to_sym
|
71
|
+
end
|
72
|
+
@log.debug ('checking ' << k.to_s) if @log
|
73
|
+
if(msg == nil && File.respond_to?(k) && ! File.send(k, file.to_s))
|
74
|
+
msg = "#{file} #{@@text_messages[k.to_sym]}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
msg
|
79
|
+
end
|
80
|
+
alias :check_file :file_check
|
81
|
+
end
|
82
|
+
|
83
|
+
=begin
|
84
|
+
# example
|
85
|
+
|
86
|
+
include File_Checking
|
87
|
+
msg = file_check('some_file.txt', [:exist?, :readable?, 'writable'])
|
88
|
+
puts msg if msg
|
89
|
+
=end
|
data/lib/logging.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
/***************************************************************************
|
4
|
+
* ©2011-2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
|
5
|
+
* *
|
6
|
+
* This program is free software; you can redistribute it and/or modify *
|
7
|
+
* it under the terms of the GNU General Public License as published by *
|
8
|
+
* the Free Software Foundation; either version 3 of the License, or *
|
9
|
+
* (at your option) any later version. *
|
10
|
+
* *
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
14
|
+
* GNU General Public License for more details. *
|
15
|
+
* *
|
16
|
+
* You should have received a copy of the GNU General Public License *
|
17
|
+
* along with this program; if not, write to the *
|
18
|
+
* Free Software Foundation, Inc., *
|
19
|
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
20
|
+
***************************************************************************/
|
21
|
+
=end
|
22
|
+
require 'logger'
|
23
|
+
require_relative 'file_checking'
|
24
|
+
|
25
|
+
=begin Creates a member @log and precede its output with the name of the class
|
26
|
+
of the object.
|
27
|
+
Example for a class-level logger:
|
28
|
+
# --------------------
|
29
|
+
class TClass
|
30
|
+
self.extend(Logging)
|
31
|
+
@@log = init_logger(STDOUT)
|
32
|
+
def test_log
|
33
|
+
@@log.info('class-level logger called from instance: ' << @@log.to_s)
|
34
|
+
@log = @@log
|
35
|
+
@log.info('AGAIN: class-level logger called from instance: ' << @log.to_s)
|
36
|
+
end
|
37
|
+
def self::test_log
|
38
|
+
@log.info('class-level logger called from class: ' << @log.to_s)
|
39
|
+
@@log.info('AGAIN: class-level logger called from class: ' << @@log.to_s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
#---------------------
|
43
|
+
Example for a object-level logger:
|
44
|
+
ATTN! This means 1 logger per object.
|
45
|
+
# --------------------
|
46
|
+
class TClass
|
47
|
+
include Logging
|
48
|
+
def initialize
|
49
|
+
init_logger(STDOUT, Logger::DEBUG)
|
50
|
+
end
|
51
|
+
def test_log
|
52
|
+
@log.debug('called test_log() ')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
=end
|
56
|
+
module Logging
|
57
|
+
include File_Checking
|
58
|
+
|
59
|
+
@@have_log = false
|
60
|
+
@@LOG_CONF = File.dirname(File.absolute_path(__FILE__)) << File::Separator << 'log.conf'
|
61
|
+
|
62
|
+
# Call this method in an instance-method (e.g. initialize() ) to define the
|
63
|
+
# object-level logger; i.e. an object-specific member @log.
|
64
|
+
# Call this method within the class-definition for a class-level logger; i.e.
|
65
|
+
# a member @log for class-level acces.
|
66
|
+
# The method returns the logger, so you can actually do what you want with it.
|
67
|
+
def init_logger(target = STDOUT, level = Logger::INFO)
|
68
|
+
# Prepare for a class-level logger. This is actually quite cool.
|
69
|
+
|
70
|
+
# ---> Ingeniuous code starts here
|
71
|
+
cn = (self.class == Class ? name : self.class.name)
|
72
|
+
# <--- Ingeniuous code ends here
|
73
|
+
|
74
|
+
# allow to override the set log-levels with an
|
75
|
+
# external configuration (log.conf).
|
76
|
+
log_conf(cn)
|
77
|
+
# Or use the defaults as set here or elsewhere...
|
78
|
+
|
79
|
+
@level ||= level
|
80
|
+
@target ||= target
|
81
|
+
|
82
|
+
@log = Logger.new(@target)
|
83
|
+
@log.level = @level
|
84
|
+
|
85
|
+
@log.formatter = proc do |severity, datetime, progname, msg|
|
86
|
+
t = Time.now
|
87
|
+
"#{cn}: #{severity} #{t.hour}-#{t.min}-#{t.sec}: #{msg}\n"
|
88
|
+
end
|
89
|
+
if ! @@have_log
|
90
|
+
@log.debug cn.dup << ' reading logging-configuration from ' << @@LOG_CONF
|
91
|
+
@@have_log = true
|
92
|
+
@log.debug('level is ' << level.to_s)
|
93
|
+
end
|
94
|
+
return @log
|
95
|
+
end
|
96
|
+
|
97
|
+
def log_label=(label)
|
98
|
+
@log.formatter = proc do |severity, datetime, progname, msg|
|
99
|
+
t = Time.now
|
100
|
+
if(label && !label.empty?)
|
101
|
+
"#{label}: #{severity} #{t.hour}-#{t.min}-#{t.sec}: #{msg}\n"
|
102
|
+
else
|
103
|
+
"#{$0}: #{severity} #{t.hour}-#{t.min}-#{t.sec}: #{msg}\n"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Set the log-target to an IO object.
|
109
|
+
def log_target=(target)
|
110
|
+
@target = target
|
111
|
+
@log = Logger.new(@@target)
|
112
|
+
@log.level = @level
|
113
|
+
end
|
114
|
+
|
115
|
+
# set the log-level
|
116
|
+
def log_level=(level)
|
117
|
+
@level = level
|
118
|
+
@log.level = @level
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
# Override or set the log-level and target-device, as set in a file 'log.conf'.
|
124
|
+
# I do not like the look of this, but it works just the way I want it to.
|
125
|
+
# "HEAVANS! Isn't there a standard way to do this in Ruby, for Christ's sake?", you say.
|
126
|
+
# Heck, I don't care. <= Read that again, I say.
|
127
|
+
def log_conf(cn = nil)
|
128
|
+
config = level = target = nil
|
129
|
+
# puts 'log-config is in ' << @@LOG_CONF
|
130
|
+
if(File::exist?(@@LOG_CONF) )
|
131
|
+
begin
|
132
|
+
conf = File.read(@@LOG_CONF)
|
133
|
+
config = instance_eval(conf)
|
134
|
+
rescue Exception => ex
|
135
|
+
STDERR.puts "WARNING! Cannot evaluate the logger-configuration!" << ' ' << ex.message
|
136
|
+
STDERR.puts "Default log-levels apply."
|
137
|
+
end
|
138
|
+
# else
|
139
|
+
# puts "Default log-levels apply."
|
140
|
+
end
|
141
|
+
|
142
|
+
if(config && config.respond_to?(:to_hash) )
|
143
|
+
config.default = nil
|
144
|
+
if cn
|
145
|
+
config = config[cn.to_sym]
|
146
|
+
else
|
147
|
+
config = config[self.class.name.to_sym]
|
148
|
+
end
|
149
|
+
|
150
|
+
if(config )
|
151
|
+
if(config.respond_to?(:to_ary) && config.size == 2)
|
152
|
+
@level, @target = config
|
153
|
+
@target.downcase!
|
154
|
+
logdir = File.dirname(@target)
|
155
|
+
msg = file_check(logdir, :exist?, :directory?, :writable?)
|
156
|
+
if(msg)
|
157
|
+
STDERR.puts "WARNING! A logfile for '%s' cannot be written to %s (%s)!" %[self.class.name, logdir, msg]
|
158
|
+
@target = nil
|
159
|
+
end
|
160
|
+
else
|
161
|
+
@level = config
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
######### test
|
169
|
+
if __FILE__ == $0
|
170
|
+
class TClass
|
171
|
+
# class level ---->
|
172
|
+
self.extend(Logging)
|
173
|
+
@@log = init_logger(STDOUT, Logger::INFO)
|
174
|
+
# <------
|
175
|
+
# object-level ---->
|
176
|
+
include Logging
|
177
|
+
# <---------
|
178
|
+
|
179
|
+
def test_log
|
180
|
+
@@log.info('class-level logger called from instance: ' << @@log.to_s)
|
181
|
+
#@log = @@log # works too
|
182
|
+
@log = TClass.class_eval{@log}
|
183
|
+
@log.info('AGAIN: class-level logger called from instance: ' << @log.to_s)
|
184
|
+
@log.debug("you won't see this on log-level INFO")
|
185
|
+
|
186
|
+
# object-level ---->
|
187
|
+
init_logger
|
188
|
+
# <-----------
|
189
|
+
@log.info("That's a different thing: " << @log.to_s << " - object-level logger!")
|
190
|
+
|
191
|
+
end
|
192
|
+
def self::test_log
|
193
|
+
@log.info('class-level logger called from class: ' << @log.to_s)
|
194
|
+
@@log.info('AGAIN: class-level logger called from class: ' << @log.to_s)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
TClass.new.test_log # class-logger + 1st object-logger
|
199
|
+
TClass.new.test_log # same class-logger + 2nd object-logger
|
200
|
+
|
201
|
+
TClass::test_log # same class-logger
|
202
|
+
puts 'And just say it once clearly: THIS IS COOOL!!'
|
203
|
+
end
|
204
|
+
#EOF
|
data/lib/timequiz.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#encoding: UTF-8
|
3
|
+
|
4
|
+
=begin
|
5
|
+
/******************************************************************************
|
6
|
+
* Copyright © 2017-2017, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
7
|
+
* *
|
8
|
+
* This program is free software; you can redistribute it and/or modify *
|
9
|
+
* it under the terms of the GNU General Public License as published by *
|
10
|
+
* the Free Software Foundation; either version 3 of the License, or *
|
11
|
+
* (at your option) any later version. *
|
12
|
+
* *
|
13
|
+
* This program is distributed in the hope that it will be useful, *
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
16
|
+
* GNU General Public License for more details. *
|
17
|
+
* *
|
18
|
+
* You should have received a copy of the GNU General Public License *
|
19
|
+
* along with this program; if not, write to the *
|
20
|
+
* Free Software Foundation, Inc., *
|
21
|
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
22
|
+
******************************************************************************/
|
23
|
+
=end
|
24
|
+
|
25
|
+
require_relative 'argparser'
|
26
|
+
require_relative 'adder'
|
27
|
+
require_relative 'color_output'
|
28
|
+
require_relative 'extstring'
|
29
|
+
require_relative 'user_input'
|
30
|
+
require_relative 'busy_indicator'
|
31
|
+
require_relative 'event'
|
32
|
+
require_relative 'logging'
|
33
|
+
|
34
|
+
require 'date'
|
35
|
+
|
36
|
+
# Main program class. All action is within the initialize() method, or, more
|
37
|
+
# precisely in the start_game() method which has to be defined by an
|
38
|
+
# interface-module.
|
39
|
+
class Timequiz
|
40
|
+
self::extend(Logging)
|
41
|
+
@@log = self::init_logger
|
42
|
+
|
43
|
+
# Find out, how the program has been called.
|
44
|
+
# In juin 2017 this can be 'timequiz' or 'timequizGtk'.
|
45
|
+
# Write a Qt-interface, create a symbolic link 'timequizQt' in
|
46
|
+
# ../../bin and add a when-clause to the case-when structure, right below the
|
47
|
+
# method (in class-scope).
|
48
|
+
# Returns true if the given executable file is named the same as the one
|
49
|
+
# called, false if they are not the same.
|
50
|
+
# Returns the name of the called executable, if no argument is given.
|
51
|
+
def self.called_as?(executable = nil)
|
52
|
+
return File::basename($0) == executable.strip if executable
|
53
|
+
return File::basename($0)
|
54
|
+
end
|
55
|
+
|
56
|
+
# This adds all the functionality of the named interface module to the
|
57
|
+
# current class.
|
58
|
+
case called_as?
|
59
|
+
# GTK-Interface
|
60
|
+
when 'timequizGtk'
|
61
|
+
# require_relative 'gtk/timequizGtk'
|
62
|
+
# include TimequizGtk
|
63
|
+
@log.info('I am sorry. But there is not Gtk-interface, for the time.')
|
64
|
+
# Text only
|
65
|
+
when 'timequiz'
|
66
|
+
require_relative 'console'
|
67
|
+
include Console
|
68
|
+
# EXAMPLE
|
69
|
+
# when 'timequizSWT'
|
70
|
+
# require_relative 'swt'
|
71
|
+
# include SWT
|
72
|
+
else
|
73
|
+
# beats me
|
74
|
+
# puts "How did you do that?"
|
75
|
+
# ... HEY! I guess: You created a link to the executable but forgot
|
76
|
+
# something else. Read the comment to the 'called_as?' method, above.
|
77
|
+
@log.error(": A user-interface \"" << called_as? << "\" has not (yet) been defined (read the code, my friend)! Aborting.")
|
78
|
+
exit false
|
79
|
+
end
|
80
|
+
|
81
|
+
def verify_prepare(file)
|
82
|
+
if(file && !file.empty? && !file.end_with?('.rb'))
|
83
|
+
file << ".rb"
|
84
|
+
end
|
85
|
+
begin
|
86
|
+
ofl = File.open(file, 'a')
|
87
|
+
if !File.readable?(file)
|
88
|
+
@log.error('The file ' << file << ' cannot be read! Aborting')
|
89
|
+
exit false
|
90
|
+
end
|
91
|
+
if(File.empty?(file) )
|
92
|
+
@log.info("The file " << file << " is empty. You must add some events to it.")
|
93
|
+
if(File.writable?(file) )
|
94
|
+
orig_file = File.dirname(__FILE__) << File::Separator << 'events.rb'
|
95
|
+
@log.debug('orig_file is ' << orig_file)
|
96
|
+
File.open(orig_file, 'r') do |ifl|
|
97
|
+
ofl.puts("# Events defined for the Timequiz game")
|
98
|
+
ofl.puts("# Lines starting with '#' are comments.\n\n# EXAMPLES:")
|
99
|
+
3.times do
|
100
|
+
line = ""
|
101
|
+
line = ifl.readline.strip until line.start_with?('$')
|
102
|
+
ofl.puts('#' << line)
|
103
|
+
end
|
104
|
+
ofl.puts("\n# Add your own events below this line\n#" << '_' * 60)
|
105
|
+
end
|
106
|
+
ofl.close
|
107
|
+
end
|
108
|
+
add_ok = require file
|
109
|
+
else
|
110
|
+
add_ok = require file
|
111
|
+
if(add_ok)
|
112
|
+
return add_ok, $events.length >= 3
|
113
|
+
end
|
114
|
+
end
|
115
|
+
rescue IOError => ex
|
116
|
+
ofl.close
|
117
|
+
@log.error('Cannot work with the given file: ' << ex.message)
|
118
|
+
exit false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def initialize(*args)
|
123
|
+
@log = @@log
|
124
|
+
# adjust log-level, if given.
|
125
|
+
# Else use what you know.
|
126
|
+
options = ArgParser.parse(*args)
|
127
|
+
$LOG_LEVEL = Logger::DEBUG if options.debug
|
128
|
+
@log.level = $LOG_LEVEL if $LOG_LEVEL
|
129
|
+
@log.debug('log_level is ' << $LOG_LEVEL.to_s)
|
130
|
+
@log.debug('options are ' << options.to_s)
|
131
|
+
# should we add only a new event to the list
|
132
|
+
@log.debug('options are : ' << options.to_s)
|
133
|
+
add_ok = game_ok = false
|
134
|
+
if(options.file)
|
135
|
+
@log.debug('shall use non-standard events file')
|
136
|
+
add_ok, game_ok = verify_prepare(options.file)
|
137
|
+
else
|
138
|
+
game_ok = require_relative 'events'
|
139
|
+
end
|
140
|
+
if(options.add)
|
141
|
+
if(add_ok)
|
142
|
+
Adder::add(options)
|
143
|
+
exit true
|
144
|
+
elsif(options.file)
|
145
|
+
@log.error('cannot add events to ' << options.file)
|
146
|
+
exit false
|
147
|
+
else
|
148
|
+
@log.error('PSE start the program with -h or --help to see an option-overview')
|
149
|
+
exit false
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# start the chosen interface
|
154
|
+
if(game_ok)
|
155
|
+
start_game
|
156
|
+
else
|
157
|
+
@log.error("Cannot play with the events in " << options.file)
|
158
|
+
@log.error("PSE verify that there are at least 3 events defined!")
|
159
|
+
exit false
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
# A dangerous method. Not only because the use of the argument is somewhat
|
166
|
+
# esotheric... This sorts the events in the *correct* order of their years.
|
167
|
+
# Any later comparison with user-provided values is based on the *correct*
|
168
|
+
# order, not the one currently at display! Although this is of interest only
|
169
|
+
# after the very first round, it caused me some headache, once the
|
170
|
+
# user-interfaces had been separated... Mind this when creating a new UI.
|
171
|
+
# The argument 'index' controlls if the displayed index should be changed to
|
172
|
+
# mirror the *correct* order of events, meaning the index from the Array + 1
|
173
|
+
# (i.e. [1,2,3...]). I forgot, how this is useful (see in 'good_order',
|
174
|
+
# below).
|
175
|
+
def sort_years(index = false)
|
176
|
+
@m_events.sort! {|f, s| f.year <=> s.year }
|
177
|
+
@m_events.each_with_index {|ev, i| ev.disp_index = i+1} if index
|
178
|
+
end
|
179
|
+
|
180
|
+
# Verifies and reports if the user-provided order is correct in the way that
|
181
|
+
# it creates a consistent timeline. The argument 'response' may be either an
|
182
|
+
# Array of Integers or just one Integer. In the latter case, an Event should
|
183
|
+
# be given, too.
|
184
|
+
def good_order(response, event = nil)
|
185
|
+
if(response.respond_to?(:to_ary) )
|
186
|
+
response_years = []
|
187
|
+
response.each_with_index {|r, i| response_years[r-1] = @m_events[i].year}
|
188
|
+
@log.debug('response is ' << response.join(', ') << "\nresponse_years is : " << response_years.join(', ') )
|
189
|
+
|
190
|
+
# do not change the displayed index
|
191
|
+
sort_years(false)
|
192
|
+
event_years = @m_events.collect{|ev| ev.year }
|
193
|
+
|
194
|
+
# Compare the order of years, not the order of events!
|
195
|
+
# There may be two or more events in the same year.
|
196
|
+
response_years == event_years
|
197
|
+
elsif(response.respond_to?(:to_int) )
|
198
|
+
# set/change the displayed index
|
199
|
+
sort_years(true)
|
200
|
+
# Compare the order of years, not the order of events!
|
201
|
+
# There may be two or more events in the same year.
|
202
|
+
@m_events[response + 1].year == event.year
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
## ---TEST
|
211
|
+
if __FILE__ == $0
|
212
|
+
qu = Timequiz.new
|
213
|
+
end
|
214
|
+
|
215
|
+
## ---END TEST
|
216
|
+
# EOF, too.
|