Hamradio contest evaluator software

Willingly I started to build this software free of charge for anyone simply coz hamradio aint just me, hamradio is about all of us.Only together can produce more quality and more value for hamradio itself.

So,  that being said I would love to see feedbacks for what is going to be universal contest evaluator, even though in this primary form is just a simple project.


23 September 2020

  • Log files can be uploaded via web page
  • Once uploaded, software will analise it and will auto respond with claimed score, computed score and validation as cabrillo file.
  • Once validated will get into real time analiser, real time meaning 0.09 seconds for an average 600 qso log file.
  • This average computing is based on single core CPU, will be split to all CPU cores/ threads to be much more faster.

So far I got stuck on computing score like instead of 3000 points computed by N1MM,  I evaluate 3020 points also 53 muliplicators instead of 54.

Could be python call_to_dxcc  PIP installer where entities are not precise ( I got to add D1M and 2E0 prefixes manually into call_to_dxcc main constructor whithin /usr/local/lib/python3.4/dist-packages/call_to_dxcc/__init__.py  ) , but I have to cross check via N1mm logs to observere where the differnce is comming from.

It is pity that ARRL entity list is so garbled and a lot of compute power is wasted to parse that list which is prone to errors.

What I am working now is  another code to reparse ARRL list into a more precise one , one that will be auto updated.

So far I am testing against an older version URI dxcc_uri = “http://www.arrl.org/files/file/DXCC/2019_Current_Deleted(3).txt” embeded in call_to_dxcc

#!/usr/bin/python3

import subprocess
import call_to_dxcc
import os

try:
    os.remove("final_score.csv")
except:
    print("Error while deleting file ", "final_score.csv")



call_list = ""
mult_list = ""
points = 0
final_score = 0
multiplicator = 0

f = open( 'final_score.csv', 'a' )

num_lines = sum(1 for line in open('yp0hq.cbr'))
file = open("yp0hq.cbr", "r")
lines=file.readlines()

for x in range(0, num_lines):

    line = lines[x]
    callsign = line.split()[8]
    country, continent, dxcc_number = call_to_dxcc.data_for_call(callsign)
    call_exist = call_list.rfind(str(callsign)+",")
    mult_exist = mult_list.rfind(str(country)+",")
    
    if (continent != "EU"):
        points = 8
    else: 
        points = 4
    if  country == "YO":
        points = 0 
    if call_exist != -1 :
        points =0 
        qso_status = "Duplicate QSO"
    else:
        qso_status =  "Valid QSO"
    if mult_exist == -1 :
        multiplicator +=1
        mult_list = str(mult_list)+str(country)+","


    final_score = final_score + points
    final_line =   str(callsign) + "\t" + str(country) + "\t" + str(points) + "\t" + str(qso_status) 

    print(final_line)    
    print( final_score )    

    uniq=  callsign+","
    call_list = call_list + uniq
    f.write(final_line+"\n")



print(final_score)
print(multiplicator)
print (mult_list)
print("final score is ",multiplicator*final_score)

f.close()

 

So, this software would be completed with some RRD web app, web config admin parameters  and real time score evaluator as final score.

It will have a page dedicated to rules set where organiser could insert any logic, also a combination of php front end and python backend would allow participants to see contest evaluation in real time.It is hard work but I say it would be a nice project to involve in.

############  END OF  2020-09- 23 ###########

28 September 2020 Status Update :

pip3 install cabrillo

So there is a module available into PIP  that will compute even faster and simpler than my aproach.

Ditched all code above and testing this route, it has it’s own matching 2 QSO’s method.

 

#!/usr/bin/python3
import os
import call_to_dxcc
from time import sleep
from cabrillo import qso
from cabrillo import QSO
from cabrillo.parser import parse_log_file
from datetime import datetime
class myClass:
    call_list = ""
    mult_list = ""
    points = 0
    final_points = 0
    final_score = 0
    multiplicator = 0
    mult_exist = ""
    mode = ""
    def log_compute(self):
        print("computing "+ logname + " log file")
        cab = parse_log_file("logs/"+str(logname))
        for line in cab.qso:
            self.dx_callsign  = str(line).split()[8]
            self.date = str(line).split()[3] + " " + str(line).split()[4][:2]+":"+str(line).split()[4][2:]
            #self.time = str(line).split()[4] #.replace('-', ',')   +','+str(line).split()[4][:2]+":"+str(line).split()[4][2:]
            self.mode = str(line).split()[2]
            self.band = str(line).split()[1]
            self.exch_sent = str(line).split()[7]
            self.exch_rcvd = str(line).split()[10]
            self.de_callsign = str(line).split()[5]
            qso1 = QSO(self.band , self.mode, datetime.strptime(self.date, '%Y-%m-%d %H:%M'), self.de_callsign, self.dx_callsign, ['599', self.exch_sent], ['599', self.exch_rcvd], t=None)

            try:
                dx_cab = parse_log_file("logs/"+self.dx_callsign+".cbr")
                for dx_line in dx_cab.qso:
                    self.dx_callsign2  = ( str(dx_line).split()[8] )
                    self.date2 = str(dx_line).split()[3] + " " + str(dx_line).split()[4][:2] + ":" + str(dx_line).split()[4][2:]
                    #self.time2 = str(dx_line).split()[4]  # .replace('-', ',')   +','+str(line).split()[4][:2]+","+str(line).split()[4][2:]
                    self.mode2 = str(dx_line).split()[2]
                    self.band2 = str(dx_line).split()[1]
                    self.exch_sent2 = str(dx_line).split()[7]
                    self.exch_rcvd2 = str(dx_line).split()[10]
                    self.de_callsign2 = str(dx_line).split()[5]
                    print (self.date2)
                    qso2 = QSO(self.band2 , self.mode2, datetime.strptime(self.date2, '%Y-%m-%d %H:%M'), self.de_callsign2, self.dx_callsign2, ['599', self.exch_sent2], ['599', self.exch_rcvd2], t=None)
                    compare_qso = qso1.match_against(qso2)
                    print(compare_qso)
                    print (qso1)
                    print (qso2)
            except:
                print("Error opening " + self.dx_callsign + ".cbr file")

            country, continent, dxcc_number = call_to_dxcc.data_for_call(self.dx_callsign)
            self.call_exist = self.call_list.rfind(str(self.dx_callsign)+",")
            self.call_list = str(self.call_list) + self.dx_callsign + ","
            self.mult_exist = self.mult_list.rfind(str(country) + ",")
            if (continent != "EU"):
                self.points = 8
            else:
                self.points = 4
            if  country == "YO":
                self.points = 0
            if self.call_exist != -1 :
                self.points =0
                self.qso_status = "Duplicate QSO"
            else:
                self.qso_status =  "Valid QSO"
            if self.mult_exist == -1 :
                self.multiplicator = self.multiplicator + 1
                self.mult_list = self.mult_list + country + ","
            self.final_points = self.final_points + self.points
            #print (str(self.date) + "," + str(self.dx_callsign) + "," + str(self.points) +"," + self.qso_status + "," + self.mode + "," + self.band + "," + self.exch_sent + "," + self.exch_rcvd)
        #print ("##### " + logname +" SUMARY #####")
        #print("points = " + str(self.final_points))
        #print( "multipliers = " + str(self.multiplicator) )
        #print ("final score = " + str(self.multiplicator*self.final_points) + " points")
        #print ("##### END SUMMARY #####")
        #print (qso1)
        #print (qso2)
for logname in sorted(os.listdir("logs/")):
        myClass().log_compute()

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *