Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » zMUD General Discussion
knuffel
Wanderer


Joined: 12 Jul 2002
Posts: 73

PostPosted: Sun Dec 08, 2002 11:47 am   

Keeping Track of Results in DB
 
Hi All,


I have been thinking about this a little and I know
zMUD has the features to do it, but my skills lack the knowledge,
thus I would like to ask if any of you could help me out on this.

I want to keep track of all my mining results
and get an overview of totals I mined weekly and a grandtotal.

Right now I will count all the different nuggets and gems
before I sell them, copy that and manually update a file keeping track
of my sells.

I was thinking it must be much easier if I could create a Database
for it that will keep track of the results.

By concept I came up with the following.

I will only add the items when I sell them, so not
updating the DB when I mined one because this would
falsify the statistics if anyone stole an item.

By executing my count I would like to add the amount I collected,
the date I collected it and the hard part some kind of grandtotal and subtotal
that is based on a week or an triggered period.

So what it looks like.

alias countmining

You count 27 golden nuggets.
You don't find any silver nugget.
You count only 1 copper nugget.
You don't find any pearls.
You count 5 gemstones.
...


This should result in updating the DB records for

gold
silver
copper
pearl


It's no problem in creating the records manually for all the items
as these don't change that often and will only change when I update
my countmining alias.

I think it would be the best way I add a new record that has
the timestamp as unique ID so it would look like

200212071931 27 - 1 - 5


Now this seems already to create my first problem as it seems I can only go to 999999 for a num field for timestamp. But I could split it up in YYMM DD HH mm so that is not such a big problem.

2002 12 07 1931 27 - 1 - 5

But then would it be possible to create a view that will count my totals or do I have to create a second DB that will calculate it.
I can make easily a view that gives me all records of one week with the filter rules, but I couldn't find a way of getting the totals out of it.

Anyone feels like they could help me out on this ?

Thanks a lot !
Knuff
Reply with quote
Kjata
GURU


Joined: 10 Oct 2000
Posts: 4379
Location: USA

PostPosted: Sun Dec 08, 2002 3:14 pm   
 
You can use the timestamp idea and put it all as one big number, but you need to use a text field instead of a number field. However, text can still be sorted the same way that numbers can and if you put it in the format of "yyyymmddhhmm", you will always be able to sort by date/time in ascending/descending order.

I trust you know how to create a new record. Basically, when you call you alias it will first empty a variable that will contain the new record and add to it the timestamp:
#VAR dbentry ""
#ADDKEY dbentry Time %time("yyyymmddhhmm")

*Note: Be sure that the name you use for the key in the record variable is the exact same name (case and all) that you have for the corresponding field in the database.

Next, triggers will match the amount you have of each material and add a key-value pair to the variable. Example:
#TRIGGER {You count (%d) golden nuggets.} {#ADDKEY dbentry Gold %1}

or for the case where you don't find any:
#TRIGGER {You don't find any golden nugget.} {#ADDKEY dbentry Gold 0}

Now, you also need to create a trigger that fires when all of the key-value pairs have been added to the record variable and adds the new record to the database. This is normally done with a trigger that fires on a blank line, but of course, this is MUD specific. Anyway, the command that the trigger would execute is:
#NEW All @dbentry

This will add the new record to the All view, but you can create other views that then sort the record by date or whatever you wish.

Finally, for the totals, you can use the %sum function. This function returns the sum of the values of a column of a specific view in the database. If you use the All view, you can get a grandtotal. If you use a specific view (one that contains only the records of a specific week, for example) you can get a subtotal.

To use this function you have two options. You can create an alias that will call the function and show you the value when you want it. Or you can create a formula field in the database whose value is what this function returns. The formula field allows you to quickly see the total when you look at the database, but you will see the same value for all the records in the current view, so it might not look as pretty as you wanted.

Kjata
Reply with quote
knuffel
Wanderer


Joined: 12 Jul 2002
Posts: 73

PostPosted: Sat Dec 14, 2002 10:55 am   
 
Hi again,

I finally sat down and try to get this to work and I ran into a little / big problem.

I wrote the initial request being far away from mu MUD and now I see the output I receive is slightly different.

>You count one hundred sixteen nuggets.

Is there an easy way to transform one hundred sixteen to 116 or would have to make a full list of written numbers converted to numbers and translate them.

Greetz
Knuff
Reply with quote
Kjata
GURU


Joined: 10 Oct 2000
Posts: 4379
Location: USA

PostPosted: Sat Dec 14, 2002 12:18 pm   
 
The easiest way, but most tedious, would be to make the list of written numbers and their values like you said. Another way, although more complicated is to try and emulate the way people convert these into numbers in their minds. For example:
one hundred sixteen

First you see "one" and then the multiplier "hundred". So now you have:
1 * 100 = 100

Next you see sixteen, so you need to add this to what you have:
100 + 16 = 116

Using this method, you greatly reduce the amount of written numbers that have to be mapped to their values, but you need to code more advanced logic than a simple lookup and replace.

Kjata
Reply with quote
knuffel
Wanderer


Joined: 12 Jul 2002
Posts: 73

PostPosted: Sat Dec 14, 2002 12:57 pm   
 
Hi Kjata,

Thanks again.

I think I will for now leave the logic go beyond me and try to go for a replace.

Thanks to your great explanation before It works like a charm in a basic config.

I searched a little deeper in the forums and found following reply of Matt Lofton to another thread

quote:

... as far as #2 goes, if you don't have a lot of numbers to convert your best bet might be a stringlist:

Numbers.alpha = "one|two|three|four|five|..."
Numbers.numeric = "1|2|3|4|5|..."

Then you can use a trigger to trigger on one or the other and do a #sub:

#trigger {({@Numbers.alpha})} {#sub {%item(@Numbers.numeric,%ismember(%1,@Numbers.alpha))}}




I looked in my statistic from before and I will most probably only have to go to 150 or 50 depending on what I want to count.

So how would I proceed to get the math done based on the trigger so it's translated correct.

Right now I have
> You count fifty-five gold nuggets.

#TRIGGER {> You count (*) gold nuggets.} {#ADDKEY dbentry gold %1}

This works fine and the value is added to the DB as a text value.

Should I create a trigger that converts the DB field gold to gold_num as to lower the overhead in a seperate trigger, or can I do the conversion in the actual trigger.

Thanks for all the help so far !

Knuff
Reply with quote
Kjata
GURU


Joined: 10 Oct 2000
Posts: 4379
Location: USA

PostPosted: Sat Dec 14, 2002 1:09 pm   
 
You can do the conversion in the trigger if you want:
#TRIGGER {> You count (*) gold nuggets.} {#ADDKEY dbentry gold %item(@Numbers.numeric, %ismember("%1", @Numbers.alpha))}

Kjata
Reply with quote
knuffel
Wanderer


Joined: 12 Jul 2002
Posts: 73

PostPosted: Sat Dec 14, 2002 1:27 pm   
 
WAUUWW !!!

THNX, works like a charm in my basic tests ... gonna get some stress test but this looks wonderfull.

Thanks again,
Knuff
Reply with quote
knuffel
Wanderer


Joined: 12 Jul 2002
Posts: 73

PostPosted: Sat Dec 14, 2002 3:49 pm   
 
Hi again,

Since the data collection works as wanted I started working on the second part of my little mission.

The views of my results.

My question is now twofold as what I am trying to do seems to fail bluntly.

- a DB view that gives me the totals of the last 7 days and is dynamicly rebuild.

As a testcase i tried to put in FILTER setting
TIMESTAMP greater than "(%time) - 70000" but this returns all records
TIMESTAMP greater than "%time - 70000" does not return any record.

This is also not a complete solution since on the first of december it is 200212010000
and distracting 70000 would not return a correct result.


- I am puzzled on how I should be able to get the results of the last week by executing a trigger
so the totals of the last week are displayed based on the ALL view. I guess if succeed in the first dynamic view I will be able to retrieve the records anyway.


Anyone a clue or direction ?

Greetz
Happy Knuff
Reply with quote
Kjata
GURU


Joined: 10 Oct 2000
Posts: 4379
Location: USA

PostPosted: Sat Dec 14, 2002 6:02 pm   
 
Ok, perhaps it's better if the timestamp is divided into two fields: Date and Time. We also need to change the way that they store their value to make the math a lot easier.

Date will contain the number of days that have passed since January 1, 2000. Time will contain the number of milliseconds that have passed since midnight of the day that Date refers to. This way, if you want the records from the past week, all you need is those records that have Date larger than the current date minus 7.

The value of Time is easy since zMUD has the pre-defined variable %secs which returns exactly what the value of Time should be. The value of Date is a little more tricky since it has to be calculated. For that reason, I have created the following variable and two aliases that work together to calculate this value. Here they are:
#VAR daysUntilMonth {0|31|59|90|120|151|181|212|243|273|304|334}
#ALIAS getLeapDays {#VARIABLE leapDays 0;#VARIABLE leapDays %eval( @leapDays + ((@curYear - 2000) / 4) + 1);#IF ((!(@curYear 4) and (@curYear 100)) or (!(@curYear 100) and !(@curYear 400))) {#IF (@curMonth < 3) {#ADD leapDays -1}};#ADD leapDays %eval( ((@curYear - 2000) / 100) * -1);#ADD leapDays %eval( (@curYear - 2000) / 400)}
#ALIAS getDate {#VARIABLE curYear %time( "yyyy");#VARIABLE curMonth %time( "m");#VARIABLE curDay %time( "d");getLeapDays;#VARIABLE date %eval( ((@curYear - 2000) * 365) + %item( @daysUntilMonth, @curMonth) + @curDay - 1 + @leapDays)}

By calling getDate, the variable @date obtains the value of the number of days that have passed since January 1, 2000 until the present day.

So, in the alias that creates the timestamp, it should contain the following instead of the previous command that created the timestamp:
getDate
#ADDKEY dbentry Date @date
#ADDKEY dbentry Time %secs

Time would probably have to be a text field since the value of %secs is a big number, but you can make Date a number field and it should work with no problems until November 27, 4737

The last problem would be creating the filter. For the records from the last seven days you could create this filter:
Date greater than %eval(@date - 7)

The only problem with this is keeping the value of @date current. For this, you could call the getDate alias in the atconnect alias in your System class that gets called each time you connect to the MUD. If the next day comes while you are connected to the MUD, you may call getDate yourself to correct its value.

Kjata
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » zMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net