Tanktalus,
my ($id_name, $filename, $last_name, $first_name, $alignment, $generic_class_name, $class_name, $generic_race, $race, $gender, $experience, $strength, $dexterity, $constitution, $intelligence, $wisdom, $charisma) = qw(test) x 17; is just a placeholder, and will be gone in the final code as will all the Data::Dumper stuff since it isn't doing me any good at the moment.
I have read, reread, and reread Text::CSV and Text::CSV_XS, and they do not tell me what I need to know, how to use the data once I get it. I tried to bind the columns, and that didn't work. I am at my wits end trying to make this work. I just don't get what Text::CSV is doing.
I can't even figure out why tie %csv, qw(Tie::IxHash); doesn't work.
I have written the two hashes in two ways, and they don't work.
%general_information = (
"class(es)" => $csv{"class_name"},
alignment => $csv{"alignment"},
race => $csv{"race"},
gender => $csv{"gender"},
);
%ability_scores = (
strength => $csv{"strength"},
dexterity => $csv{"dexterity"},
constitution => $csv{"constitution"},
intelligence => $csv{"intelligence"},
wisdom => $csv{"wisdom"},
charisma => $csv{"charisma"},
);
%general_information = (
"class(es)" => $csv->{class_name},
alignment => $csv->{alignment},
race => $csv->{race},
gender => $csv->{gender},
);
%ability_scores = (
strength => $csv->{strength},
dexterity => $csv->{dexterity},
constitution => $csv->{constitution},
intelligence => $csv->{intelligence},
wisdom => $csv->{wisdom},
charisma => $csv->{charisma},
);
I am missing a big piece of this puzzle and don't know what it is.
Have a nice day!
Lady Aleena
| [reply] [d/l] [select] |
You're not really explaining what you want to do. Because, as far as I can tell, your first script works just fine. Once you get the $hr, you print Dumper($hr), and the output you see to your screen will look like:
$VAR1 = {
'class_name' => '1st level Fighter/1st level Thief/1st level
+ Mage',
'intelligence' => '18',
'wisdom' => '14',
'charisma' => '15',
'experience' => '0',
'dexterity' => '18',
'strength' => '18(93)',
'last_name' => 'Zendelic',
'generic_class_name' => 'Fighter-Thief-Mage',
'filename' => '!ZeKy',
'generic_race' => 'Half-Elf',
'constitution' => '17',
'race' => 'Half-Elf',
'alignment' => 'Neutral Good',
'gender' => 'Female',
'id_name' => 'Kymaria_Zendelic',
'first_name' => 'Kymaria'
};
That means that $hr is a reference to a hash (see the braces? Just like in your perl code when you want a reference to an anonymous hash). You could print ref($hr) to see that it says HASH. That means that if you put the rest of your character-handling-code inside that loop, and use $hr as a reference to a hash containing all the variables you care about, you should be off and running:
while (defined (my $hr = $csv->getline_hr($io))) {
# use $hr->{id_name} to get the id_name
}
You can't use Tie::IxHash because, well, you're not populating the hash. You'll probably have to extract things yourself in the order you want, but that's ok, you already have the order you want as @names. (Using DBD::CSV allows you to do this, too, but we'll stick with what you have for now.)
So, you'll have this loop:
while (defined (my $hr = $csv->getline_hr($io))) {
my %general_information = (
"class(es)" => $hr->{class_name},
alignment => $hr->{alignment},
race => $hr->{race},
gender => $hr->{gender},
);
my %ability_scores = (
strength => $hr->{strength},
dexterity => $hr->{dexterity},
constitution => $hr->{constitution},
intelligence => $hr->{intelligence},
wisdom => $hr->{wisdom},
charisma => $hr->{charisma},
);
# do stuff with the above hashes.
}
Mind you, that does seem somewhat repetitive, and I'm not a fan of repetition, so ...
while (defined (my $hr = $csv->getline_hr($io))) {
my %general_information = (
"class(es)" => $hr->{class_name},
map { $_ => $hr->{$_} } qw/alignment ra
+ce gender/;
);
my %ability_scores = (
map { $_ => $hr->{$_} } qw/strength
dexterity
constitution
intelligence
wisdom
charisma/
);
# here you can use them, same as previous example.
list_loop(\%general_information);
list_loop(\%ability_scores);
}
Now, in these cases, you can use Tie::IxHash if you want to control the order of the keys, otherwise the order will be different each time you run (possibly). | [reply] [d/l] [select] |
Tanktalus,
If I knew you a bit better, I would kiss you all over the face. The best I can do is give you some zen-cookies. You answered the big question I didn't know to ask, what was the proper hashref. This is what happens when one leaves a script for a long while and comes back. Without semantic names, one forgets what is what. So, I was left with a whole bunch of letters that were meaningless and not knowing what was doing what, because I am still not good at this. Use this as a cautionary tale about nonsemantic variable names.
I still couldn't get it to dump the big hash tied up, but that is okay. I don't need it.
Here is the script that works!
While you are not a fan or repetition, I am not that big a fan of sprawl. I hope you don't mind.
Have a nice day!
Lady Aleena
| [reply] [d/l] |
I didn't follow all the details in this thread re Text::CVS, but your comment about DBD::CSV stands out as a good idea!
I have a project with a CSV file that I am starting soon and plan to go with the DBI approach. I had played with this on Unix a while back and it seemed to work great The problem was that the CSV module for the DBI wasn't available on ActiveState and I couldn't use it for Windows based applications - so this idea went on back burner. That problem has evidently been solved with Perl 5.10 and current modules!
If I'm right about this, using the DBI will allow me to write code that could be used with some other DB at some later time if necessary.
Oh well, not directly applicable to the OP's problem at hand, but I thought that this DBI with CSV is now possible on Windows was worth a mention. A thought for other projects.
The code looks like connecting to other underlying Databases:
use DBI; #need to have DBD::CSV installed for this script
my $db = DBI->connect("DBI:CSV:f_dir=./DEMO.db")
or die "Cannot connect: $DBI::errstr";
....run DBI SQL stuff ...
Update:There is a thing that I've found out with using CSV files...I have some users who haven't written any code in their life, never seen an SQL or a Perl statement, but yet can do magic with modern spreadsheets! A lot of the old limits are gone like number of lines, and there are multiple pages, etc. Sometimes sending CSV spreadsheet data works to everyone's advantage. The users can sometimes do amazing stuff! | [reply] [d/l] |
my $dbh = DBI->connect ("dbi:CSV:", undef, undef, {
f_dir => "DEMO.db:",
f_ext => ".csv/r",
f_schema => undef,
PrintError => 1,
RaiseError => 1,
});
The disadvantage of this when the data set grows bigger is that all of your CSV data is kept in memory, and probably even twice. That, plus some meta-data will quickly gobble up most of your available valuable memory. If you want an intermediate database to make a move to something real later on, and still want portability, skip DBD::CSV and use DBD::SQLite instead. It is lightweight, fast and portable and supports a lot more than CSV.
Enjoy, Have FUN! H.Merijn
| [reply] [d/l] |
Thanks! for your suggestion of SQLite, I will see if I can get it on Windows! After I wrote my post, I generated the starting database, about 14K lines. This will grow in a very short time to about 50K lines. I know from experience and a lot of testing on other Perl applications that I won't start having trouble until memory footprint reaches > 1/2 GB. But that can happen quickly!The basic thing is to get started using SQL for this stuff! I want to port the existing process first (which can be done with some "lite" tools), then on the "features to do list" are things that will require MUCH larger DB's. So, yes, portability of code is a factor if it is possible to do.
| [reply] |