Point System ideas

General discussions about the website's layout and functionality
Redfist
Global Moderator
Posts: 59
Joined: January 22nd, 2012, 3:38 pm

Re: Point System ideas

Post by Redfist »

Corfman Clan wrote:I can do this. I'm not worried about doing it. If I don't do it, I have complete confidence in Redfist being able to. Right now, we're working on getting the data into the system. That entails things like connecting to Groundspeak's servers to retrieve pocket queries and cache logs. Parsing through the pocket queries, updating the database with the pocket query and log data. Properly handling exceptions that may/will occur. Managing the tasks that do all that. Scheduling activities to keep the data up to date, and so on. There's a lot to do and we'll generate thousands of lines of code to get it done. Compared to everything else, calculating a cache's score is simply peanuts. If you must opine about something, please pick something more interesting than this. :shock:

...A little earlier my wife said I needed to get out. :lol:
Love it!

As CC mentioned, we're in the very beginnings of the foundational infrastructure stage. Infrastructure here is 90% of the job. The particulars around how to compute points is a very minor work items. It's that oh-so-sought-after cherry that sits alone atop a mountain of whipped cream, chocolate sauce, ice cream, bowl, placemat, table, floor all existing in a house.

--Redfist
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

For your viewing pleasure:

Code: Select all

private double calculateTotalScore()
{
    int yearsOld;
    int days;
    int daysInYear;

    DateTime beginning = gcData.PublishedDate == null ? gcData.PlacedDate : gcData.PublishedDate;
    DateTime today = DateTime.Today;

    DateTime LastAnniversary = new DateTime(today.Year, beginning.Month, beginning.Day);
    DateTime nextAnniversary;

    if (LastAnniversary <= today)
    {
        // The cache's anniversary already passed this year
        yearsOld = today.Year - beginning.Year;
        nextAnniversary = LastAnniversary.AddYears(1);
    }
    else
    {
        // The cache's anniversary is later this year
        yearsOld = today.Year - beginning.Year - 1;
        nextAnniversary = LastAnniversary;
        LastAnniversary = LastAnniversary.AddYears(-1);
    }
    daysInYear = (nextAnniversary - LastAnniversary).Days;
    days = (today - LastAnniversary).Days;

    return pointsPerYear * (yearsOld + (double)days / (double)daysInYear);
}
The above has one major flaw that will be corrected. Since you guys have been so interested in this, I'll sit back and enjoy letting you figure out what it is :twisted:
Corfman Clan wrote:(I should also point out that I'm counting a cache as one day old the day it is published, not the day after. This means, for example, that a cache published on Jan 1, 2011, is a year old Dec 31, 2011, not Jan 1, 2012. I did this so a cache would never be 0 days old.)
Also, the above code doesn't follow what I wrote here. To do so, I'd need to subtract one day from the "beginning."
Image
User avatar
jcanyoneer
Posts: 41
Joined: January 18th, 2012, 9:46 am

Re: Point System ideas

Post by jcanyoneer »

Seems over complicated to me...all that anniversary stuff....
:lol:
I think I like this better:

private double calculateTotalScore()
{
int yearsOld;
int days;
int daysInYear;

DateTime beginning = gcData.PublishedDate == null ? gcData.PlacedDate : gcData.PublishedDate;
DateTime today = DateTime.Today;
return Points = DateTime((today-beginning).Year*365+(today-beginning).Month*365/12+(today-beginning).Day
}
:roll:
I'm no coder so I assume this would not even work (I don't know the DateTime syntax)-but I thought it would still be fun to throw it out!

Looks like you don't have the 100 point multiplier in your last equation to make the 100 point system, right? Or does this just calculate how many points are possible in a year?
JCanyoneer
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

jcanyoneer wrote:Seems over complicated to me...all that anniversary stuff....
All the anniversary stuff gets us is whether the year has 365 or 366 days.
jcanyoneer wrote:I think I like this better:...
Try this:

Code: Select all

private double calculateTotalScore()
{
    DateTime beginning = gcData.PublishedDate == null ? gcData.PlacedDate : gcData.PublishedDate;
    return (DateTime.Today-beginning).Days;
}
jcanyoneer wrote:Looks like you don't have the 100 point multiplier in your last equation to make the 100 point system, right? Or does this just calculate how many points are possible in a year?
It's there, it's just held in the pointsPerYear variable. That way, I can set it to 120 if I want ;)

Code: Select all

return pointsPerYear * (yearsOld + (double)days / (double)daysInYear);
So did you figure out the flaw in my code? Maybe it needs to be part of a puzzle cache? :lol:
Image
rocketsciguy
Posts: 145
Joined: January 18th, 2012, 9:55 am

Re: Point System ideas

Post by rocketsciguy »

Yo no hablo C code. I was trained on Fortran, believe it or not, and yes in the 21st century. Et je ne parle pas la OOP, either, but I will give it the old college try.

Let's see, I must assume the datatype, structure, object or whatchamacallit "DateTime" comes from an included header file way before and as such need not be defined here. The inline if syntax looks right after a quick search, parentheses don't appear to be necessary for the order of operations to work.... Is this C#? DateTime appears to be a C# language object, or maybe .NET? Ich verstehe diesen Sprache noch schlimmer!

Well, assuming all the function overloading works like its supposed to, and the methods (or thingamajiggers) after the dots do what they imply they do, and all the variables you're using (specifically gcData) are within the function's scope, I can only see one possible problem comparing this code to another sample using C# DateTime.

Code: Select all

//  DateTime today = DateTime.Today;        // IS WRONG
    DateTime today = System.DateTime.Today; // IS RIGHT ???
Well, maybe one more thing. This could be a problem in some languages, and I don't know whether/how C-family languages handle automatic datatype conversions... poorly I think.

Code: Select all

return pointsPerYear * (yearsOld + (double)days / (double)daysInYear);
Your return statement here is multiplying pointPerYear (unknown to us whether declared as integer or real) with a sum that is an integer plus a real divided by a real. You're adding a double precision quotient to the integer yearsOld. Is that the problem? If so, every cache is going to come out with a score of 0, 100, 200, 300, etc. I hope I'm right! :D

Otherwise, I think your algorithm is sound, and now I know why you weren't concerned about handling anniversary dates and leap years... you've got an object/class thingamadoodle that does it for you! I thought you'd be doing this in a query with SQL, but looks like you're crunching numbers this way and then pushing it out to your database.

This is why you're doing this, not me. But if you need some MATLAB code debugged, I'm your man! Have an ODE to integrate, just ask. Linearize equations of motion in vector notation? You should see my thesis! But C-code... let me get back to you on that.

I should really not check this board late at night... because at oh-dark-thirty it's off to work... where, ironically, I will be writing VisualBasic modules (another OOP language I don't understand) for an MS Access database.... :?
afudc
Benefactor
Posts: 26
Joined: January 22nd, 2012, 10:22 pm

Re: Point System ideas

Post by afudc »

When DGP was up and running I always thought that I would prefer a 10 point per month system. As rocketsciguy pointed out that isn't as simple as it sounds. All things considered I am now thinking that keeping it at 100 points per year may be best.
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

afudc wrote:When DGP was up and running I always thought that I would prefer a 10 point per month system. As rocketsciguy pointed out that isn't as simple as it sounds. All things considered I am now thinking that keeping it at 100 points per year may be best.
Actually, you can get close enough using my algorithm above and setting the pointsPerYear variable to 120 :)
Image
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

rocketsciguy wrote:Is this C#? DateTime appears to be a C# language object, or maybe .NET? Ich verstehe diesen Sprache noch schlimmer!
Yep, it's C#.
rocketsciguy wrote:I can only see one possible problem comparing this code to another sample using C# DateTime.

Code: Select all

//  DateTime today = DateTime.Today;        // IS WRONG
    DateTime today = System.DateTime.Today; // IS RIGHT ???
Nope, they are the same. At the start of the code, there is a using System statement that scopes in DateTime. In your example above, the IS RIGHT line is actually wrong if no using System statement was included, and should be:

Code: Select all

System.DateTime today = System.DateTime.Today
rocketsciguy wrote:Well, maybe one more thing. This could be a problem in some languages, and I don't know whether/how C-family languages handle automatic datatype conversions... poorly I think.

Code: Select all

return pointsPerYear * (yearsOld + (double)days / (double)daysInYear);
Your return statement here is multiplying pointPerYear (unknown to us whether declared as integer or real) with a sum that is an integer plus a real divided by a real. You're adding a double precision quotient to the integer yearsOld. Is that the problem? If so, every cache is going to come out with a score of 0, 100, 200, 300, etc. I hope I'm right! :D
Nope it's not that. I casted days and daysInYear to double for that exact reason.

Here's a hint. The problem won't show up until :arrow: next year
Image
rocketsciguy
Posts: 145
Joined: January 18th, 2012, 9:55 am

Re: Point System ideas

Post by rocketsciguy »

Found it. Like almost any algorithm involving dates, the problem is either on New Years' or Leap Day. This time both. I put your algorithm in a spreadsheet ('cuz I don't do C) and put together this:
Don't publish your cache on Leap Day and expect to get full LCP points for it! :)
Don't publish your cache on Leap Day and expect to get full LCP points for it! :)
DateAlgorithmTable.png (17.46 KiB) Viewed 16136 times
When going from 31 Dec to 01 Jan, we change from the THEN branch of the IF block to the ELSE branch. When the cache is published on 29 Feb, we have a discontinuity when switching from one branch to the other. On 31 Dec, nextAnniversary is set to 28 Feb 2013, LastAnniversary = 29 Feb 2012, and days = (31 Dec 2012) - (29 Feb 2012) = 306 days (which is right). The next day on 01 Jan, nextAnniversary = 01 Mar 2013, LastAnniversary = 01 Mar 2012, and days = (01 Jan 2012) - (01 Mar 2012) = 306 days (which is wrong).

And I'm not sure whether daysInYear ought to be 366 or 365 when the publish date is on Leap Day. If 29 Feb 2012 is Day 1 for the cache (because we don't want there to be a Day 0), then 28 Feb 2013 ought to be Day 366 of the cache. You algorithm comes up with days = 364 and daysInYear = 365 and a score of 99.726 in this scenario (at 100 points/year). But you mentioned that:
Corfman Clan wrote:(I should also point out that I'm counting a cache as one day old the day it is published, not the day after. This means, for example, that a cache published on Jan 1, 2011, is a year old Dec 31, 2011, not Jan 1, 2012. I did this so a cache would never be 0 days old.) ... Also, the above code doesn't follow what I wrote here. To do so, I'd need to subtract one day from the "beginning."
...so I'm not sure whether the fix here will fix part of the problem I describe in this paragraph.

I'm sure things like this are part of the reason why jcanyoneer and I were suggesting basing the score system on elapsed days not years and fraction of years. These kinds of bugs can be very difficult to find and often harder to correct without introducing more bugs. Glad to hear you already have a fix in mind -- I don't have one.

Or, if you want to look at the open source code for LibreOffice (or OpenOffice) Calc YEARFRAC and DAYS functions, you might find an existing algorithm that does what you need and been vetted by a larger computing community than our humble group of cachers. :P
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

rocketsciguy wrote:Found it. Like almost any algorithm involving dates, the problem is either on New Years' or Leap Day. This time both.
Actually, that's not the bug. What you show is a side effect of the bug. Just to blow the suspense, the bug is with how the anniversary days are created for caches placed on leap day (Feb. 29) for non leap years.

Code: Select all

lastAnniversary = new DateTime(today.Year, beginning.Month, beginning.Day);
doesn't make sense on non-leap years. In fact, in C#, the code will throw an exception (a bad thing) when attempting to set the date to Feb. 29 of a non-leap year. If the code didn't throw the exception, then the side effect you point out will occur.

To stop the exception, I modified the above line of code to:

Code: Select all

bool placedOnFeb29 = false;
if (beginning.Month == 2 && beginning.Day == 29)
{
    placedOnFeb29 = true;
    lastAnniversary = new DateTime(today.Year, 2, 28);
    lastAnniversary = lastAnniversary.AddDays(1);
}
else
{
    lastAnniversary = new DateTime(today.Year, beginning.Month, beginning.Day);
}
As mentioned, that just causes an exception to not be thrown. There is still problems that cause the side effects. Those are caused when either lastAnniversary or nextAnniversary fall on a leap year. Similar adjustments are made to get the proper anniversary date back to Feb. 29th and not Mar. 1.
Image
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

Here's the updated version of the algorithm to calculate a cache's score:

Code: Select all

private double calculateTotalScore()
{
    int yearsOld;
    int days;
    int daysInYear;

    bool placedOnFeb29 = false;

    DateTime beginning = (gcData.PublishedDate == null) ? gcData.PlacedDate : gcData.PublishedDate;

    DateTime today = DateTime.Today;

    DateTime lastAnniversary;
    DateTime nextAnniversary;

    // If the cache's beginning is February 29, then we need to account
    // for that when setting the anniversary.
    if (beginning.Month == 2 && beginning.Day == 29)
    {
        placedOnFeb29 = true;
        lastAnniversary = new DateTime(today.Year, 2, 28);
        lastAnniversary = lastAnniversary.AddDays(1);
    }
    else
    {
        lastAnniversary = new DateTime(today.Year, beginning.Month, beginning.Day);
    }

    if (lastAnniversary <= today)
    {
        // The cache's anniversary already passed this year
        yearsOld = today.Year - beginning.Year;

        if (placedOnFeb29)
        {
            nextAnniversary = new DateTime(lastAnniversary.Year + 1, 2, 28);
            nextAnniversary = nextAnniversary.AddDays(1);
        }
        else
        {
            nextAnniversary = lastAnniversary.AddYears(1);
        }
    }
    else
    {
        // The cache's anniversary is later this year
        yearsOld = today.Year - beginning.Year - 1;
        nextAnniversary = lastAnniversary;

        if (placedOnFeb29)
        {
            lastAnniversary = new DateTime(lastAnniversary.Year - 1, 2, 28);
            lastAnniversary = lastAnniversary.AddDays(1);
        }
        else
        {
            lastAnniversary = lastAnniversary.AddYears(-1);
        }
    }

    daysInYear = (nextAnniversary - lastAnniversary).Days;
    days = (today - lastAnniversary).Days;

    return pointsPerYear * (yearsOld + (double)days / (double)daysInYear);
}
Image
rocketsciguy
Posts: 145
Joined: January 18th, 2012, 9:55 am

Re: Point System ideas

Post by rocketsciguy »

Not too bad if I may say so. Without digging in and trying to write and compile C#, this time I just assumed the program could do what you asked it to and looked for flaws in the algorithm (i.e. I went to pseudocode-level abstraction, not knowing what DateTime C# objects can do).
Corfman Clan wrote:
rocketsciguy wrote:Found it. Like almost any algorithm involving dates, the problem is either on New Years' or Leap Day. This time both.
Actually, that's not the bug. What you show is a side effect of the bug. Just to blow the suspense, the bug is with how the anniversary days are created for caches placed on leap day (Feb. 29) for non leap years.

Code: Select all

lastAnniversary = new DateTime(today.Year, beginning.Month, beginning.Day);
doesn't make sense on non-leap years. In fact, in C#, the code will throw an exception (a bad thing) when attempting to set the date to Feb. 29 of a non-leap year. If the code didn't throw the exception, then the side effect you point out will occur.
When mimicking that line of code in my spreadsheet I used the DATE(year, month, day) function, which handles non-real dates like that pretty well. If you tell it "=DATE(2000,1,0)" you get 12/31/99. If you subtract 6 months from April 20, 2008 with "=DATE(2008,4-6,20) you get 10/20/07, and if you ask for February 29, 2013 it gives you 03/01/13.
Corfman Clan wrote:Here's the updated version of the algorithm to calculate a cache's score: <snip ~65 lines of code>
Isn't it ridiculous what it takes to compute the age of something?! :? :roll:
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

rocketsciguy wrote:Isn't it ridiculous what it takes to compute the age of something?! :? :roll:
Well, there's really only about 27 statements :geek:
You also mentioned before:
rocketsciguy wrote:I know how surprisingly and strangely difficult it can be to do date differences like you've shown
That is very true. Working with dates and our calendar system is not a trivial task, even with libraries that ease things quite a bit. If we had to deal with time zones and such, that would really complicate things :?
Image
AllWright
Posts: 14
Joined: January 19th, 2012, 3:35 pm

Re: Point System ideas

Post by AllWright »

I like 100 points per year.

On a related note, I would love to see the points granted to each finder based on DAYS found, not actual number of find logs. Here's my reasoning: There are several true backcountry caches I have investigated online that look really intriguing, even though they would take significant effort to get to. Unfortunately, others have felt the same and have organized groups to go get them. So, the cache may have been logged 30 times in 5 years, but has really only been found 4 or 5 times, just mostly by groups.

The DGP point system ranks these caches fairly low because of the many individual logs, but they've truly only been 'found' a handful of times. The DGP point system actually discourages a cacher from going after these exceptional backcountry caches, rather than encouraging them. Also, the DGP point system has encouraged me to be more of a lone cacher, rather than going with others. This is not really safe in the backcountry (even with my SPOT Messenger), nor is it as fun as going with someone else. If we divided the available points by DAYS found, then the caches would retain their true value based on how often they were actually found, rather than just logged.

I realize that caches are often found by different cachers not in a group on the same day, but this is going to be very rare for the true backcountry caches, so it would really only affect low-point caches anyway. It would actually make them worth a little more - not necessarily a bad thing.
AllWright
Posts: 14
Joined: January 19th, 2012, 3:35 pm

Re: Point System ideas

Post by AllWright »

Actually, while I like 100 pts. per year, it really isn't important. I can certainly live with a point per day. It is obviously easier to code, based on the above thread! :) Though like has been said, computing points is the least of the coding that needs to be done...
User avatar
Corfman Clan
Global Moderator
Posts: 914
Joined: January 17th, 2012, 12:21 am

Re: Point System ideas

Post by Corfman Clan »

AllWright wrote:On a related note, I would love to see the points granted to each finder based on DAYS found, not actual number of find logs. Here's my reasoning: There are several true backcountry caches I have investigated online that look really intriguing, even though they would take significant effort to get to. Unfortunately, others have felt the same and have organized groups to go get them. So, the cache may have been logged 30 times in 5 years, but has really only been found 4 or 5 times, just mostly by groups...
This is already being discussed here
Image
kenneprt&Broncho87
Posts: 1
Joined: February 18th, 2012, 6:45 pm

Re: Point System ideas

Post by kenneprt&Broncho87 »

The reason we are all looking for a new site is being deprived of the dgp. Why change a system that has motivated so many goal oriented cachers. We like the old 100 point system. Thanks for all the work going into this project.
User avatar
cosninocanines
Posts: 28
Joined: January 20th, 2012, 7:26 am

Re: Point System ideas

Post by cosninocanines »

me no habla nada! Thanks again I see you folks who comprehende all this are hard at work and I guarantee all the rest of us appreciate it mucho grande.
Times Fun when your having Flies!
Kermit
Redfist
Global Moderator
Posts: 59
Joined: January 22nd, 2012, 3:38 pm

Re: Point System ideas

Post by Redfist »

Then.... along came a database guy and made it all straightforward. SQL Server can do date math and keep leap years in mind. I currently am just using DATEDIFF in SQL to compute the age of the cache. I am currently computing as 100 points per year but if we ever decide to change that, it's just as simple as changing the "100" to anything else.

It's fun watching the leaderboards take shape. I don't have all of the AZ data downloaded on my laptop yet (CC does however) so my leaderboards are off. I only have data up through mid 2009 but that doesn't matter for making the queries.

It's starting to take shape!
rocketsciguy
Posts: 145
Joined: January 18th, 2012, 9:55 am

Re: Point System ideas

Post by rocketsciguy »

Redfist wrote:Then.... along came a database guy and made it all straightforward. SQL Server can do date math and keep leap years in mind. I currently am just using DATEDIFF in SQL to compute the age of the cache. I am currently computing as 100 points per year but if we ever decide to change that, it's just as simple as changing the "100" to anything else.
Awesome! So (e.g.) "SELECT ... DATEDIFF("yyyy",[PubDate],Date()) AS CacheAge FROM ... " will return the cache age in years and fractions of a year? That would make it extremely simple to also switch to 1 point per day, or 10 points per month if those ideas gained traction.

I just did an experiment in MS Access 2007, but I found it only produces integers. The documentation says it returns a Variant (Long) datatype, i.e. an integer. Does it prodcue fractions in whatever SQL system you're using, or are you using one calculation for year, another for days since anniversary the way Corfman's C# code does?

Sorry, not trying to poke holes but trying to understand and offer whatever modicum of "help" I can. ;)
Post Reply