Class: TopCoderPythonTester

Inherits:
TopCoderTester show all
Defined in:
lib/tcjudge.rb

Instance Method Summary collapse

Methods inherited from TopCoderTester

#convert_seconds_to_points, #perform_cut, #split_parameters

Constructor Details

#initialize(problem_definition, test_cases = nil, tmpdir = nil, code = nil, interpreter = nil) ⇒ TopCoderPythonTester

Returns a new instance of TopCoderPythonTester.



1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
# File 'lib/tcjudge.rb', line 1365

def initialize(problem_definition, test_cases = nil, tmpdir = nil, code = nil, interpreter = nil)
  @problem_definition = problem_definition

  if test_cases != nil && tmpdir != nil && code != nil && interpreter != nil
    @test_cases = test_cases
    @tmpdir = tmpdir

    @tester_source_name = "#{@tmpdir}/tester.py"

    open(@tester_source_name, 'w').write "#{ perform_cut(code) }\n#{ generate_tester() }"

    @interpreter = interpreter
  end
end

Instance Method Details

#convert_type(type_name) ⇒ Object



1256
1257
1258
# File 'lib/tcjudge.rb', line 1256

def convert_type(type_name)
  return type_name
end

#generate_parameter(type, name, value) ⇒ Object



1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
# File 'lib/tcjudge.rb', line 1346

def generate_parameter(type, name, value)
  if type =~ /\[\]$/
    # array
    element_type = type.sub(/\[\]$/, '')
    elements = split_parameters(value[1, value.length - 2])
    parameter = "        #{ name } = [ "
    parameter += elements.map { |element| generate_primary_value(element_type, element) }.join(', ')
    parameter += " ]\n"
    return parameter
  else
    return "        #{ name } = #{ generate_primary_value(type, value) };\n"
  end
end

#generate_parameters(parameters_string) ⇒ Object



1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
# File 'lib/tcjudge.rb', line 1324

def generate_parameters(parameters_string)
  result = ''
  parameters = split_parameters(parameters_string)

  @problem_definition[:parameters].each_with_index do |parameter, index|
    result += generate_parameter(parameter[:type], "param#{index}", parameters[index])
  end

  return result
end

#generate_primary_value(type, value) ⇒ Object



1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
# File 'lib/tcjudge.rb', line 1335

def generate_primary_value(type, value)
  case type
  when 'String'
    return "#{value}"
  when 'long'
    return "#{value}L"
  else
    return value
  end
end

#generate_result_comparison_functionObject



1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
# File 'lib/tcjudge.rb', line 1282

def generate_result_comparison_function
  func = <<EOS
  def compareResult(self, from_, to_):
EOS
  case @problem_definition[:return_type]
  when 'double'
    func += <<EOS
      return abs(from_ - to_) <= 1e-9
EOS
  when 'double[]'
    func += <<EOS
      return reduce(lambda x, y: x && (abs(y[0] - y[1]) <= 1e-9), zip(from_, to_), True)
EOS
  else
    func += <<EOS
      return from_ == to_
EOS
  end

  return func;
end

#generate_result_dumper_functionObject



1304
1305
1306
# File 'lib/tcjudge.rb', line 1304

def generate_result_dumper_function
  return "    def dumpResult(self, result_):\n        print result_\n"
end

#generate_signatureObject



1230
1231
1232
1233
# File 'lib/tcjudge.rb', line 1230

def generate_signature()
  return @problem_definition[:method_name] + '(self, ' + \
    (@problem_definition[:parameters].map { |parameter| parameter[:name] }).join(', ') + ')'
end

#generate_testerObject



1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
# File 'lib/tcjudge.rb', line 1260

def generate_tester()
  tester = <<EOS
class Tester:
#{ generate_result_comparison_function() }
#{ generate_result_dumper_function() }
EOS

  @test_cases.length.times do |index|
    tester += generate_tester_function(index)
  end

  tester += <<EOS
import sys

if __name__ == '__main__':
  tester = Tester()
  sys.exit(eval('tester.test' + sys.argv[1] + '()'))
EOS

  return tester
end

#generate_tester_callObject



1360
1361
1362
1363
# File 'lib/tcjudge.rb', line 1360

def generate_tester_call
  return "        result = target.#{ @problem_definition[:method_name] }(" +
    (0 .. (@problem_definition[:parameters].length - 1)).map { |index| "param#{ index }" }.join(', ') + ");"
end

#generate_tester_function(index) ⇒ Object



1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
# File 'lib/tcjudge.rb', line 1308

def generate_tester_function(index)
  return <<EOS
  def test#{index}(self):
      target = #{ @problem_definition[:class_name] }();
#{ generate_parameters(@test_cases[index][:input]) }
#{ generate_tester_call() }
#{ generate_parameter(@problem_definition[:return_type], "expected", @test_cases[index][:output]) }
      if self.compareResult(result, expected):
          return 0
      else:
          self.dumpResult(result)
          return 1

EOS
end

#generate_timestampObject



1215
1216
1217
# File 'lib/tcjudge.rb', line 1215

def generate_timestamp
  return "# TIMESTAMP: #{ Time.now.to_i }"
end

#get_template(template_proc) ⇒ Object



1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
# File 'lib/tcjudge.rb', line 1236

def get_template(template_proc)
  if template_proc.nil?
    return <<EOS
# -*- coding: utf-8 -*-

import math,string,itertools,fractions,heapq,collections,re,array,bisect

# CUT begin
#{ generate_timestamp() }
# CUT end

class #{ @problem_definition[:class_name] }:
  def #{ generate_signature() }:

EOS
  else
    return instance_eval(&template_proc)
  end
end


1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
# File 'lib/tcjudge.rb', line 1219

def print_points(code)
  code.match(/^# TIMESTAMP: ([0-9]+)$/) do |backward|
    seconds = Time.now.to_i - backward[1].to_i
    @problem_definition[:points].each_with_index do |total, i|
      points = convert_seconds_to_points(seconds, total)
      warn "Score: #{ sprintf('%.2f', points) } / #{ total } (#{ seconds } secs)"
    end
  end
  return
end

#run(index) ⇒ Object



1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
# File 'lib/tcjudge.rb', line 1380

def run(index)
  tester_options = "#{@interpreter} #{@tester_source_name} #{index}"
  if system(tester_options)
    return :AC
  else
    case $?.exitstatus
    when 1
      return :WA
    else
      if $?.exited?
        return :UNKNOWN_ERROR
      else
        puts "\nCompiller Options: #{ @compile_options }"
        puts "Tester Options: #{tester_options}"
        puts "Exit Status: #{$?}"
        return :RUNTIME_ERROR
      end
    end
  end
end