Writing to file?

illarion

Member
I'd like to create my own mini logfile, a quick one line summary of the entire session results, say.

Is there any way in ASH to write to/append to an arbitrary file?
 

Theraze

Active member
Well, let's see what ASH knows about...

Code:
> ashref file

boolean file_to_map( string, aggregate )
boolean file_to_map( string, aggregate, boolean )
boolean map_to_file( aggregate, string )
boolean map_to_file( aggregate, string, boolean )
Code:
> ashref log

void logprint( string )
int [int] reverse_numberology( )
int [int] reverse_numberology( int, int )
string [int] session_logs( int )
string [int] session_logs( string, int )
Looks like your only real "save to an arbitrary file" option is basically map_to_file, but you can define the map record however you like... for example, anchoring with my_daycount and then including whatever session summary brings you joy.
 

illarion

Member
Hehe, those two ashrefs were the first thing I tried :) I was vaguely aware of map_to_file back when I actually knew what I was doing with ASH, but I don't remember the first thing about it - and it didn't occur to me for this task. I remember Veracity wrote a tutorial on maps somewhere in the official documentation, guess that's the first thing I should read up :)

Thanks for the pointers!
 

fronobulax

Developer
Staff member
Hehe, those two ashrefs were the first thing I tried :) I was vaguely aware of map_to_file back when I actually knew what I was doing with ASH, but I don't remember the first thing about it - and it didn't occur to me for this task. I remember Veracity wrote a tutorial on maps somewhere in the official documentation, guess that's the first thing I should read up :)

Thanks for the pointers!

http://kolmafia.sourceforge.net/advanced.html#maps

and/or

http://wiki.kolmafia.us/index.php?title=Data_Structures
 

illarion

Member
...and I have it doing exactly what I want with map_to_file :) (Which is great, incidentally - somehow it's easier to write a record to file in ASH than in just about any "real" language I've used. Veracity* is awesome :) ).

Thanks again for the pointers folks!

(*I think I'm right in remembering it was Veracity who did the work on maps? Apologies if I'm miscrediting there).
 

illarion

Member
Yes, I invented ASH maps (and records and arrays). Glad you like them!

I do indeed, especially in combination. (And Mafia and ASH remain one of the very best things about KoL!)

Good to see you again Veracity, very glad to see you're still around.

As ever, thanks for everything you've done for us!
 

illarion

Member
...I don't suppose there's a way of putting a header in a map_to_file created file is there? (In such a way that file_to_map can read it back happily)

(Purpose - I'm writing a load of integers, for later analysis in Excel, and it's a bit hard to read)

By hand would be fine - only has to be done once, after all - although in code is always preferable :) Is there a comment character that file_to_map respects?

(I realise I could fake it with a dummy key, and writing all the values as strings rather than ints - but I'd prefer to keep the datatypes if possible)
 

illarion

Member
Unfortunately, # doesn't seem to do the trick - my log files end up without the commented header.

(I presume file_to_map reads the file just fine, ignoring the commented character, but map_to_file overwrites it?)
 

Bale

Minion
Correct. Mafia ignores the octothorp commented line.

map_to_file() always overwrites all data currently existing in a file. Anything else would be bad. There is no command to merge new data into an existing file.
 

illarion

Member
Correct. Mafia ignores the octothorp commented line.

map_to_file() always overwrites all data currently existing in a file. Anything else would be bad. There is no command to merge new data into an existing file.

Fair enough, meaning there is no way to write a header, other than forcing all variables to string and using a dummy key for the header?
 
Fair enough, meaning there is no way to write a header, other than forcing all variables to string and using a dummy key for the header?

If your key is an int value (like daycount or whatever), you could just use -1 as your 'header key' and pretend the minus sign is your comment character. I just tried this and it did exactly what you'd expect:

Code:
ash string[int] thing; thing[-1]="header"; thing[0]="item 1"; thing[1]="item 2"; map_to_file(thing,"thingtest.txt");

I'm not sure how your map actually looks though. If your key field is a string you could just make one starting with "!" or something that'd sort it to the top. I'm not sure what'd happen if you started a key string with "#" and then wrote it..
 

illarion

Member
My key field is a date, so I can easily sort that to the top by using 1/1/1970 (or whatever ASH's 0-date is, or well anything pre 2017 will do). So yeah, I can write the first line in the file, no problem.

The problem is that my values are all ints, but I'd like to have descriptive (i.e. string) column/field names when I later import into Excel or similar for analysis.

Since we're talking about a plain text file, I guess I should have just handled all the int values as strings in the first place, as the representation in the file would ultimately be the same, and it would allow me to write whatever I liked as a header. I wasn't sure how nicely ASH handles converting things, whether I'd have to explicitly cast, and, well, it was working, the header was a "nice to have" rather than essential, and I haven't yet gotten around to fiddling with it :)
 

Theraze

Active member
ASH will pull in whatever you tell it exists in the file. If you tell it that the file has strings instead of ints, it will pull in the ints as strings instead. Alternatively, you could potentially add a new third to your record definition and have both string and int. Up to you.
 

illarion

Member
I understand that. I meant that, having pulled the (now string) values into Mafia, I wasn't 100% sure how much hassle it would be to then treat them as numbers. Whether 1000 = "1000", you might say, or if I need to explicitly cast the string values to ints, or whatever.

Obviously it can be done, and I don't expect it's much hassle at all - I just haven't got to it ;)
 

xKiv

Active member
Maybe it's RFE time?
New version of map_to_file with a new parameter, an array of "column headers" that will be written in a (commented out) header line?

(At first I thought it would be enough if something like this would happen:
Code:
record sometype { int id; string desc; int value; };
sometype [int] map;
...
map_to_file(map,"filename");
// file will look something like this - column names derived from record attributes' names
# id desc value
1 1 text1 1
...

But the map can have multiple keys, and then if map_to_file had some ability to specify names for key collumns, why not all columns)
 

Pazleysox

Member
PHP:
{
boolean [string] clannies = who_clan();
foreach clannie in clannies {

map_to_file( clannies , "whosinclan.txt" );
}
I've figured this out. This was pretty simple. I can recall the file, as needed also. That part isn't hard.

Is there a way to have the information returned in a single line?

So info in whosinclan.txt looks like this:
PazSox
Easyfax
This member
That member


But when the info is returned to mafia, it looks like this:
PazSox, Easyfax, This member, That member

I'm trying to figure out how to return what users are online, and active in chat, and what users are "AFK"...
 

Bale

Minion
But when the info is returned to mafia, it looks like this:
PazSox, Easyfax, This member, That member

Please explain how this could happen. Provide your code that produces this outcome, because I'd have to put in some intentional effort to replicate your result. Maybe I just don't know what you mean.
 
Top