Loading ...
Sorry, an error occurred while loading the content.

bring in arrays by position?

Expand Messages
  • Eric Via
    A true perl beginner here - I have lines of numbers that look something like this - and each time the numbers are the different but the format and layout is
    Message 1 of 10 , May 4, 2001
    • 0 Attachment
      A true perl beginner here - I have lines of numbers that look
      something like this - and each time the numbers are the different but
      the format and layout is always the same, example:

      3939839392839000000003939 3900340293939 111 39393999
      777777772 3939
      3988888843900000039393933 3222229990000 002 44444444
      900000033 7777
      3932222392839000000003939 3777340293939 111 39393999
      777777772 3939

      Now I understand from my learning how to use our friend PERL to set
      PARTS or fields of these records, but I want to open the file, read
      each line like the above - and in each line cut (as in UNIX cut) to
      an array -

      How can I make it so? For instance if an invoice in the above
      records is always at position 4-9, how can I assign something like
      $invoice to positions 4-9?? And then each position 1-3 is a part
      number and I want it to be $PARTNO ???

      I thought about mixing some UNIX with PERL - but gosh I'm TRYING to
      learn some things about PERL and so I want to do it the PERL way.

      But now what I don't get is - so I read line one and assign scalars
      to parts of that line - if I do the same to the NEXT record, line 2 -
      I'd then be re-assigning the same names and I'd loose them from the
      first record!??!!? so....

      So if I have a $PARTNO (scalar?) for EACH of the above lines -
      like %PARTNO1, PARTNO2, PARTNO3, etc?? However I don't necessarily
      want to MANUALLY do this either - is there a way of saying -
      something to the effect of: "read in positions 1-3 for each record
      (line) and call it "PARTNOn" - and "n" is 1 to the end of the file,
      then go to the next record" (There could be thousands of these lines)

      I know I'm asking a lot - and so I appreciate any help or direction
      any one of you fine folks could provide me.

      Eric, flabbergasted in Texas



      --
      ---------------------------
      Eric Via
      ericvia@...
      My home page: http://web2.airmail.net/ericvia/ericpage.html
      (Buddhism, VW New Beetle, Mercedes, Spam, Jokes, D.B. Cooper,
      Trains, & more!)
      -----------------------------
      It is not our preferences that cause problems but our attachment to
      them. - Buddha
    • vallinis@yahoo.com
      Hallo I am a beginner as well, but maybe at times that between beginners we can undesratnd each other better :) Please beware all the following could be
      Message 2 of 10 , May 4, 2001
      • 0 Attachment
        Hallo

        I am a beginner as well, but maybe at times that between beginners we
        can undesratnd each other better :)
        Please beware all the following could be throughly wrong but I found
        in my life that the best way to learn is by making mistakes, dunno
        why.

        I have not thoroughly understood your qustion but I think that maight
        be of some utility the following:
        Obviously, you can rwad the file by using OPEN(FILEname ecc...
        Then you can loop with a while(FILEhandle)
        If you know that som,ething is between postion 4 and 9, all you'd
        have to do to assing to invoice is:
        $invoice=substr($_,4,10)
        as far as I understand, whereas $_ is the variable in the while loop.

        You should consider building arrays of hashes or hashes of arrays. I
        repeat I have not understood clearly what you need, maybe you can
        carify.
        $PARTNO could be a one name variable to store all if it is a one
        entry array:
        @PARTNO=();
        You allocate a hash
        %HASH=();
        You assign to the only entry in @PARTNO the hash:
        $PARTNO[0]=%HASH;

        You can then populate the object in the while loop with something
        sorts:
        $PARTNO[0]{$_}=$invoice;

        In this fashion when you have to retrieve the data, you have one
        single entry which always carries the same name ( $PARTNO[0] ) and
        you can find your objects by referencing the line (example line 4)
        $PARTNO[0]{4};
        which should carry (if the $invoice, built at the "$_" "moment" -
        line: that is-, was built correctly) the substring (4,10).

        Uhmmm....
        ciao

        Alberto .·. Vallini
        vallinis@... - vallini@...
        "Every soul which has acquired any truth, should be safe from harm
        until another period." [R.W.Emerson]



        --- In perl-beginner@y..., Eric Via <ericvia@a...> wrote:
        > A true perl beginner here - I have lines of numbers that look
        > something like this - and each time the numbers are the different
        but
        > the format and layout is always the same, example:
        >
        > 3939839392839000000003939 3900340293939 111 39393999
        > 777777772 3939
        > 3988888843900000039393933 3222229990000 002 44444444
        > 900000033 7777
        > 3932222392839000000003939 3777340293939 111 39393999
        > 777777772 3939
        >
        > Now I understand from my learning how to use our friend PERL to
        set
        > PARTS or fields of these records, but I want to open the file, read
        > each line like the above - and in each line cut (as in UNIX cut) to
        > an array -
        >
        > How can I make it so? For instance if an invoice in the above
        > records is always at position 4-9, how can I assign something like
        > $invoice to positions 4-9?? And then each position 1-3 is a part
        > number and I want it to be $PARTNO ???
        >
        > I thought about mixing some UNIX with PERL - but gosh I'm TRYING
        to
        > learn some things about PERL and so I want to do it the PERL way.
        >
        > But now what I don't get is - so I read line one and assign
        scalars
        > to parts of that line - if I do the same to the NEXT record, line
        2 -
        > I'd then be re-assigning the same names and I'd loose them from the
        > first record!??!!? so....
        >
        > So if I have a $PARTNO (scalar?) for EACH of the above lines -
        > like %PARTNO1, PARTNO2, PARTNO3, etc?? However I don't necessarily
        > want to MANUALLY do this either - is there a way of saying -
        > something to the effect of: "read in positions 1-3 for each record
        > (line) and call it "PARTNOn" - and "n" is 1 to the end of the file,
        > then go to the next record" (There could be thousands of these
        lines)
        >
        > I know I'm asking a lot - and so I appreciate any help or
        direction
        > any one of you fine folks could provide me.
        >
        > Eric, flabbergasted in Texas
        >
        >
        >
        > --
        > ---------------------------
        > Eric Via
        > ericvia@a...
        > My home page: http://web2.airmail.net/ericvia/ericpage.html
        > (Buddhism, VW New Beetle, Mercedes, Spam, Jokes, D.B. Cooper,
        > Trains, & more!)
        > -----------------------------
        > It is not our preferences that cause problems but our attachment to
        > them. - Buddha
      • Eric Via
        On 5/5/01, with the clock reading 2:09 AM +0000, vallinis@yahoo.com took a sip of coffee, stared into the email screen, and with the greatest of confidence
        Message 3 of 10 , May 4, 2001
        • 0 Attachment
          On 5/5/01, with the clock reading 2:09 AM +0000, vallinis@...
          took a sip of coffee, stared into the email screen, and with the
          greatest of confidence and grace, and at around 160 words a minute,
          began to type: :

          >Hallo
          >
          >I am a beginner as well, but maybe at times that between beginners we
          >can undesratnd each other better :)

          You bet!! I think so!

          >Please beware all the following could be throughly wrong but I found
          >in my life that the best way to learn is by making mistakes, dunno
          >why.

          Indeed it is - and I've made my share of them - I should be an
          expert by now! :-)

          >I have not thoroughly understood your qustion but I think that maight
          >be of some utility the following:
          >Obviously, you can rwad the file by using OPEN(FILEname ecc...
          >Then you can loop with a while(FILEhandle)

          GOOD!

          >If you know that som,ething is between postion 4 and 9, all you'd
          >have to do to assing to invoice is:
          >$invoice=substr($_,4,10)

          I'm doing both of the above steps right now and it's WORKING
          PERFECTLY!!!! THANKS!


          I'm playing with this part - and then will move on to the rest of
          your helpful email - about using hashes and such - VERY nice! I'm
          going to experiment around with the above for now until I better
          understand it.

          THANKS SO MUCH!!!! You're a very kind person and I appreciate your
          taking the time to help a stranger!

          Have a GREAT weekend Alberto!!!!

          Eric
          --
          ---------------------------
          Eric Via
          ericvia@...
          My home page: http://web2.airmail.net/ericvia/ericpage.html
          (Buddhism, VW New Beetle, Mercedes, Spam, Jokes, D.B. Cooper,
          Trains, & more!)
          -----------------------------
          It is not our preferences that cause problems but our attachment to
          them. - Buddha
        • Charles K. Clarkson
          ... You seem to be saying that the first line would translate from: 3939839392839000000003939 39003402939 . . . to: part number: 393 invoice: 983939
          Message 4 of 10 , May 4, 2001
          • 0 Attachment
            Eric Via wrote:
            : A true perl beginner here - I have lines of numbers that
            : look something like this - and each time the numbers are
            : the different but the format and layout is always the same,
            : example:
            :
            : 3939839392839000000003939 3900340293939 111 39393999
            : 777777772 3939
            : 3988888843900000039393933 3222229990000 002 44444444
            : 900000033 7777
            : 3932222392839000000003939 3777340293939 111 39393999
            : 777777772 3939
            :
            : Now I understand from my learning how to use our friend
            : PERL to set PARTS or fields of these records, but I want to
            : open the file, read each line like the above - and in each line
            : cut (as in UNIX cut) to an array -
            :
            : How can I make it so? For instance if an invoice in the
            : above records is always at position 4-9, how can I assign
            : something like $invoice to positions 4-9?? And then each
            : position 1-3 is a part number and I want it to be
            : $PARTNO ???

            You seem to be saying that the first line would translate
            from:
            3939839392839000000003939 39003402939 . . .

            to:
            part number: 393
            invoice: 983939

            Is that correct? If so:

            while ( <FILE> ) {
            my ($part_number, $invoice_number) = /(\d{3})(\d{6})/;
            . . .
            }

            This could probably be done faster with 'substr', but I
            find /(\d{3})(\d{6})/ easier to read.

            :
            : I thought about mixing some UNIX with PERL - but gosh
            : I'm TRYING to learn some things about PERL and so I
            : want to do it the PERL way.
            :
            : But now what I don't get is - so I read line one and assign
            : scalars to parts of that line - if I do the same to the NEXT
            : record, line 2 - I'd then be re-assigning the same names and
            : I'd loose them from the first record!??!!? so....
            :
            : So if I have a $PARTNO (scalar?) for EACH of the
            : above lines - like %PARTNO1, PARTNO2, PARTNO3,
            : etc?? However I don't necessarily want to MANUALLY
            : do this either - is there a way of saying - something to the
            : effect of: "read in positions 1-3 for each record (line)
            : and call it "PARTNOn" - and "n" is 1 to the end of the
            : file, then go to the next record" (There could be
            : thousands of these lines)

            It depends on what you need to do with that data after
            you have read it from the file and it depends on how the
            data is organized in the files. You haven't said if the
            invoices are unique. A six-digit invoice number can
            represent 1 million invoices, so a few thousand lines
            might all be unique.
            If all the invoices are unique, then a hash might be
            best:

            # Example data:
            # $invoice{$invoice_number} = $part_number

            my %invoice;
            while ( <FILE> ) {
            my ($part_number, $invoice_number) = /(\d{3})(\d{6})/;
            $invoice{$invoice_number} = $part_number;
            }

            Now you can refer to each invoice by the invoice number.

            print $invoice{983939};


            -------
            If the invoice numbers are _not_ unique, a hash will still
            work, but the part numbers would probably work best in
            an array. Since a hash can only contain a scalar, we can
            store an array reference:

            # Example data:
            # $invoice{$invoice_number}[0] = $part_number
            # $invoice{$invoice_number}[1] = $part_number
            # $invoice{$invoice_number}[2] = $part_number

            my %invoice;
            while ( <FILE> ) {
            my ($part_number, $invoice_number) = /(\d{3})(\d{6})/;
            push @{$invoice{$invoice_number}}, $part_number;
            }

            We can refer to each invoice by the invoice number, but
            each invoice is now an array of part numbers:

            print $invoice{983939}[0];

            my $part_quantity = @{$invoice{983939}};
            print "Invoice 983939 has $part_quantity part numbers.\n";

            This is an example of a hash of arrays. Look at perldsc for
            more ideas.

            -------
            If the invoice numbers are _not_ unique and you want to
            keep track of part number quantities, a hash will work but
            you may wish to represent the part numbers as another
            hash:

            # Example data:
            # $invoice{$invoice_number}{$part_number} = quantity

            my %invoice;
            while ( <FILE> ) {
            my ($part_number, $invoice_number) = /(\d{3})(\d{6})/;
            $invoice{$invoice_number}{$part_number}++;
            }


            This is an example of a hash of hashes. Look at perldsc for
            more ideas.



            With a better idea of what you want to do with the data
            once you have it, you can make better decisions about the
            data structure used in your perl program. With the help of
            'each', 'keys', 'values', and hash slices you can get write
            really convenient subs.

            For a simple hash we could write a quick missing
            invoice sub:

            sub missing_invoices ($$\%);

            # print missing invoices for EOM reckoning:
            print join "\n", missing_invoices 983930, 983940, %invoice;

            sub missing_invoices ($$\%) {
            my ($lower, $upper, $invoice_hash_ref) = @_;
            return grep !exists $$invoice_hash_ref{$_}, $lower .. $upper;
            }


            Give us a clue as to what you want to do with your data
            and we'll be happy to lend a hand.

            HTH,
            Charles K. Clarkson
          • vallinis@yahoo.com
            ciao Eric, well no surprise that I work at night. In greek mithology Athena, spouse to Jupiter, was the goddess of knowledge and she had two carachteristics:
            Message 5 of 10 , May 5, 2001
            • 0 Attachment
              ciao Eric,

              well no surprise that I work at night. In greek mithology Athena,
              spouse to Jupiter, was the goddess of knowledge and she had two
              carachteristics: she was a warrior goddess (to outline that knowledge
              can conquer you a Kingdom) and her holy animal was the owl: that is,
              she was a goddes of the night: when it is 2 o'clock in the night, and
              you're nothing more than a ghost, that's the time knowledge starts
              flying in the sky like an owl.
              To get back to perl, and to keep the conversation between beginners,
              obviously mine where only hints, so for instance once you know you
              could use open() you'd better check for the open() method syntax on
              some book, and similarly the while loop needs the barckets if I'm not
              mistaken: while(<FILEhandle>).

              As for the idea of building array of hashes, that's called DATA
              structure.
              It is a critical point, as I've started understanding only recently
              by trials and errors (more of the latter: every trial carries a
              grapefruit of errors, regularly... I think no matter how experienced
              you are, errors will be like the force in Star wars: will be with
              you).
              So before you think about how to solve a problem, always think FIRST
              how you could structure the data you are going to work in. Setting
              the methods to populate and retrieve those data should be the second
              step.
              Programming means, most of the time, this: being able to master
              LOOPS, especially nested ones, and being able to reference the
              objects. Once you master that it is like when you amster Tables in
              html: you master the language and all you need is to learn its
              specific synatxes (this darn thing of the modules in perl is driving
              me crazy...).
              So remember you can have:

              ARRAYS of ARRAYS - $entry[0][0]
              ARRAYS of HASHES - $entry[0]{key}
              HASHES of ARRAYS - $entry{key}[0]
              HASHES of HASHES - $entry{key}{key2}

              The foruth one still causes troubles to me...
              An Hash has this meaningful and dramatic advance: you can reference
              the object directly by its key: that is, you do not have to loop it
              to find out a matching entry, which saves time when your data occupy
              a significant chunk of memory. Unlike JavaScript, where you could
              build pseudo hashes, Perl provides you with the foreach loop method
              which allows you to loop the hash too, in case you need.

              Beware, hashes can return only values:
              foreach $index(keys %hash){...stuff...}
              In the loop you can extract the VALUE of a key by
              $hash{$index}
              But the method values() doesn't allow you to extarct the key. If for
              some reasons you need to inspect the keys, you cannot use the method
              values(): it doesn't return the key (sadly... and illogically enough).
              So to get the keys bear in mind that, if I am not mistaken and I
              could well be, the key in the loop above is... $index itself!

              Saying Perl means saying Hash. It's a hash world. And actually not
              just perl. Arrays must be envisoned like hashes, whereas the key is a
              number. If it happens to you to wonder what the implicit way Perl is
              representing some data in its interpreter inner misteryous workings,
              odds are that if you guess it is representing data like the value or
              the keys of a hidden hash, you bet it right.
              Good luck!


              --- In perl-beginner@y..., Eric Via <ericvia@a...> wrote:
              > On 5/5/01, with the clock reading 2:09 AM +0000, vallinis@y...
              > took a sip of coffee, stared into the email screen, and with the
              > greatest of confidence and grace, and at around 160 words a
              minute,
              > began to type: :(...snip...)
              >

              Alberto .·. Vallini
              vallinis@... - vallini@...
              "Every soul which has acquired any truth, should be safe from harm
              until another period." [R.W.Emerson]
            • Gordon Stewart
              ... Does /( d{3})( d{6})/ mean :- get a 9 digit/character number/word, & split it into 2 variables, 1 with 3 characters & one with 6 ? Is that right ? - Still
              Message 6 of 10 , May 6, 2001
              • 0 Attachment
                > Message: 1
                > Date: Sat, 5 May 2001 08:45:17 -0500
                > From: "Charles K. Clarkson"
                > <c_clarkson@...>
                > Subject: Re: bring in arrays by position?
                >
                > part number: 393
                > invoice: 983939
                >
                > Is that correct? If so:
                >
                > while ( <FILE> ) {
                > my ($part_number, $invoice_number) =
                > /(\d{3})(\d{6})/;
                > . . .
                > }
                >

                Does /(\d{3})(\d{6})/ mean :- get a 9 digit/character
                number/word, & split it into 2 variables, 1 with 3
                characters & one with 6 ?

                Is that right ? - Still learning new tricks.

                Gordon.


                =====
                new_zealand-help@yahoogroups.com
                http://n-zealand.hypermart.net/cgi-bin/mylinks/view.cgi

                ____________________________________________________________
                Do You Yahoo!?
                Get your free @... address at http://mail.yahoo.co.uk
                or your free @... address at http://mail.yahoo.ie
              • Charles K. Clarkson
                ... Yes, more specifically: my ($part_number, $invoice_number) = / # start pattern match - short for m/ ( # start a grouping - can be
                Message 7 of 10 , May 6, 2001
                • 0 Attachment
                  Gordon Stewart <gordonistewart_nz@...>:
                  :
                  : Does /(\d{3})(\d{6})/ mean :- get a 9 digit/character
                  : number/word, & split it into 2 variables, 1 with 3
                  : characters & one with 6 ?
                  :
                  : Is that right ? - Still learning new tricks.
                  :

                  Yes, more specifically:

                  my ($part_number, $invoice_number) =
                  / # start pattern match - short for m/
                  ( # start a grouping - can be referred to as $1
                  \d # match a digit [0-9]
                  {3} # exactly 3 in a row
                  ) # end first grouping
                  ( # start a grouping - can be referred to as $2
                  \d # match a digit [0-9]
                  {6} # exactly 6 in a row
                  ) # end second grouping
                  / # end of pattern match
                  x; # allow white space in regular expressions

                  Using the x modifier you can leave the above in your
                  script for future reference. When we write as above the
                  pattern match is returned as a list with 2 elements:

                  ($3_digit_match, $6_digit_match);

                  To include error handling we might have also written:

                  my ($part_number, $invoice_number) =
                  ($1, $2) if /(\d{3})(\d{6})/;

                  or:

                  my ($part_number, $invoice_number) = ($1, $2) if
                  / # start pattern match - short for m/
                  ( # start a grouping - can be referred to as $1
                  \d # match a digit [0-9]
                  {3} # exactly 3 in a row
                  ) # end first grouping
                  ( # start a grouping - can be referred to as $2
                  \d # match a digit [0-9]
                  {6} # exactly 6 in a row
                  ) # end second grouping
                  / # end of pattern match
                  x; # allow white space in regular expressions


                  HTH,
                  Charles K. Clarkson


                  The only dumb question is the one you don't ask.
                • tstraub@gmx.net
                  Damien, thanks for your reply. My INI looks like this: -- START INI -- [section2] -- END INI -- After the WriteINI it looks like this -- START INI --
                  Message 8 of 10 , May 7, 2001
                  • 0 Attachment
                    Damien,

                    thanks for your reply.

                    My INI looks like this:

                    -- START INI --
                    [section2]
                    -- END INI --

                    After the WriteINI it looks like this

                    -- START INI --
                    [section2]
                    TestKey=This is a test
                    -- END INI --

                    Your script seems to be a neat solution getting around using a
                    already written module. But I wonder why this stuff is not working
                    properly with the module Win32::AdminMisc which has much more
                    practical functions which do work.

                    Tim

                    --- In perl-beginner@y..., "Damien Carbery" <daymobrew@y...> wrote:
                    > The man of the long posts, Charles K. C., posted code to read and
                    > write INI files:
                    > http://groups.yahoo.com/group/perl-beginner/message/1706
                    >
                    > I've used the code and it works (though I think it looks for
                    entries
                    > with a space on either side of the equal signs).
                    >
                    > --- In perl-beginner@y..., tstraub@g... wrote:
                    > > Hi,
                    > >
                    > > I am trying to read a value with the ReadINI function of the
                    > > Win32::AdminMisc module.
                    > > All I get is a special character, a triangle showing to the right.
                    > > If I make a WriteINI of the same module to the testini.ini it
                    works
                    > > well. The key is added.
                    > > Only reading is impossible!
                    > >
                    > > This is my code (nothing special):
                    > >
                    > > -- START CODE --
                    > >
                    > > use Win32::AdminMisc;
                    > >
                    > > $File = "C:/Winnt/testini.ini";
                    > >
                    > > Win32::AdminMisc::WriteINI( $File, "section2", "TestKey", "This
                    is a
                    > > test" );
                    > >
                    > > $Value = Win32::AdminMisc::ReadINI(
                    $File, "section2", "TestKey" );
                    > > print "Value: <$Value>\n";
                    > >
                    > >
                    > > -- END CODE --
                    > >
                    > > And this is my Result:
                    > >
                    > > -- START RESULT --
                    > >
                    > > Value: <?>
                    > >
                    > > -- END RESULT
                    > >
                    > > The file testini.ini is located in C:\WINNT. So what I am doing
                    > wrong
                    > > here???
                    > >
                    > > Any suggestions?
                    > >
                    > > Tim
                  Your message has been successfully submitted and would be delivered to recipients shortly.