views:

105

answers:

4

For an assignment in college, we have to make a script in Perl that allows us to manage an inventory for an e-store. (The example given was Amazon). Users can make orders in a fully text-based environment and the inventory must be updated when an order is completed.

Every item in the inventory has 3 to 4 attributes: a product code, a title, a price and for some an amount (MP3's for example do not have this attribute)

Since this is my first encounter with Perl, I don't really know how to start. My main problem is how I should "implement" the inventory in the program. One of the functions of the program is searching trough the titles. Another is to make an order, where the user should give a product code.

My first idea was a hash with the productcode as key. But if I wanted to search in the titles that could be a problem because of this: the hashkey would be something like DVD-123, the information belonging to that key could be "The Green Mask 12" (without quotes) where the 12 indicates how many of this DVD are currently in stock. So I'd have to find a way to ignore the 12 in the end.

Another solution was to use the title as the key, but that would prove cumbersome too I think.

Is there a way to make a hash table with 2 keys, and when I give only one it returns an array with the other values? (Including the other key and the other information) That way I could use another key depending on what info I need from my inventory.

We have to read the default inventory from a text file looking like this:

MP3-72|Lady Gaga - Kiss and Run (Fear of Commitment Monster)|0.99  
CD-400|Kings of Leon - Only By The Night|14.50|2  
MP3-401|Kings of Leon - Closer|0.85  
DVD-144|Live Free or Die Hard|14.99|2  
SOFT-864|Windows Vista|49.95  
A: 

you can use a database such as sqlite, mysql etc to store you inventory data instead of text files. You can then use sql commands to query/update/delete/select from the database and manipulate your inventory data easily

ghostdog74
It seems a pretty good solution, but i'm also sure that we are not allowed to use such a utility. Everything must be coded using just the "basic" perl code. (i.e. no external use)Too bad :(
Harm De Weirdt
A: 

There are a lot of questions in there. One of the easy ones is how to make hashes containing lists.

There isn't a hash with two keys, but hashes are happy to point "leftward and rightward", for example:

$inventory{$title} = $product_code;
$inventory{$product_code} = $title;

if and only if you can be certain that you won't have a disc titled "DVD123". Using two hashes would be safer and more readable:

$inventory_by_title{$title} = ...
$inventory_by_code{$product_code} = ...
msw
+3  A: 

Since your course presumably does not cover SQL or databases, you may find it useful to represent your inventory as a hash of hashes.

Inventory items will be hash references:

my $die_hard_4 = { code => 'DVD-144', title => 'Live Free or Die Hard', price => 14.99, stock => 2 };

Your inventory itself will be a hash:

my %inventory;
$inventory{'DVD-144'} = $die_hard_4;

You can create another hash to index your inventory by title:

my %inventory_by_title;
$inventory_by_title{'Live Free or Die Hard'} = $die_hard_4;

All that remains is to parse the inventory file format into a hashref like the one above. As a quick example:

my %inventory;
my %inventory_by_title;

while ( <> ) {   # for each line of input
    chomp;  # remove trailing newline
    my ($code, $title, $price, $amount) = split /\|/;  # split by '|' character
    my $item = {
        code => $code,
        title => $title,
        price => $price,
        stock => $amount,
    };
    $inventory{$code} = $item;
    $inventory_by_title{$title} = $item;
}

Hope this helps you get started.

rjh
Hash references are different from hashes: they are constructed with {} (or \%hash) instead of (), and are accessed with $hash->{key} rather than $hash{key}. In Perl, hashes cannot have other hashes or arrays as values, so you must pass a reference to them instead.
rjh
+1  A: 
#!/usr/bin/perl

use strict; use warnings;
use YAML;

my @store;

while ( my $inv = <DATA> ) {
    chomp $inv;
    last unless $inv =~ /\S/;

    my ($id, $title, $price, $stock) = split qr{\|}, $inv;
    $stock ||= 0;
    my ($type, $code) = split /-/, $id;
    push @store, {
        type  => $type,
        code  => $code,
        title => $title,
        price => $price,
        stock => $stock,
    };
}

print "DVDs\n";
print Dump [ grep { $_->{type} eq 'DVD'} @store ];

print "Products that cost less than \$15\n";
print Dump [ grep { $_->{price} < 15 } @store ];

print "Products that are in stock\n";
print Dump [ grep { $_->{stock} } @store ];

print "Products with 'of' in the title\n";
print Dump [ grep { $_->{title} =~ /of/ } @store ];

__DATA__
MP3-72|Lady Gaga - Kiss and Run (Fear of Commitment Monster)|0.99
CD-400|Kings of Leon - Only By The Night|14.50|2
MP3-401|Kings of Leon - Closer|0.85
DVD-144|Live Free or Die Hard|14.99|2
SOFT-864|Windows Vista|49.95
Sinan Ünür