in reply to Re^4: seeking advice on loops
in thread seeking advice on loops

I highly suggest fixing that identation scheme. It really does make it harder to read. That said, the whitespace between chunks of code is well-placed.

Also, I continue to suggest that you have "use strict;" near the top of your program as well.

Notice in your input loop that the scalars that you're putting into @item are also the hash keys you're using for %qty and %price. This would suggest that you want to use the item names in @item as your keys for output as well. Thus, you're looping on the @item list (which is your list of keys), and you can output from all at the same time.

Your output loop, as it is, becomes something like:

foreach my $item (@item) { print "Item: $item\n"; print "Quantity: $qty{$item}\n"; }
Note also how I put in a "my" there for $item so that it would pass strict. I hope that you can extend this to include the output for your price as well.

Good luck!

Replies are listed 'Best First'.
Re^6: seeking advice on loops
by sierrastar (Sexton) on Oct 10, 2005 at 19:08 UTC

    thanks for all your great advice and wisdom...here is the somewhat finished code. I dont know what use strict is but I could not get the script to run correctly with it. I am sure it is a problem on my end and it is good advice...

    I was suppossed to write a subroutine to process the arrays and hashes but I just ended up inserting the foreach loop to do that...not sure how to turn that section into a subroutine with global variables??

    #!/usr/bin/perl -w #cash register and print receipt program my (@items, %qty, %price); #User input here print "Please enter your first and last name\n"; chomp (my $name = <STDIN>); print "Please enter your state sales tax in percentage (i.e. 7.75)\n"; chomp (my $tax = <STDIN>); $taxrate = $tax / 100; # enter loop to capture customer information here my $continue='Y'; while ($continue eq 'Y'){ print "Please enter an item or product name\n"; chomp ($itemname = <STDIN>); push @item, $itemname; print "Please enter the quantity of the item\n"; chomp ($itemquantity = <STDIN>); $qty{$itemname} = $itemquantity; print "Please enter the price of the item (no \$ please)\n"; chomp ($itemprice = <STDIN>); $price{$itemname} = $itemprice; print "Would you like to add another item? - Y or N\n"; chomp ($continue = <STDIN>); } # process subtotal and print receipt output here foreach $item (@item) { print "Item: $item\n"; $q_item = $qty{$item}; print "Quantity: $qty{$item}\n"; $p_item = $price{$item}; print "Price: \$$price{$item}\n"; $itemtotal = $q_item * $p_item; print "Item total: \$$itemtotal\n"; $subtotal += $itemtotal; print "Your current subtotal is: \$$subtotal\n"; } #print totals and tax here print "Purchase Subtotal: $subtotal\n"; print "Sales Tax Rate: $tax\n"; my $totaltax = $subtotal * $taxrate; print "Total Sales Tax = \$$totaltax\n"; my $totalamount = $subtotal + $totaltax; print "The total amount of this sale is: \$$totalamount\n"; #print the customer name and current date and time print "\n"; print "Customer: $name\n"; print "\n"; my $now = localtime time; print "Current Date and Time: $now\n";

    also I tried an "if" statement to test the $continue variable for the proper answer but I could not get that to loop until the right answer "Y" or "N" was given so I took that bad code out

    I can't tell you how much I appreciate your advice - I am learning slowly!

    sierra

      Since this is homework, I'm not going to go rewrite anything. I will, however, help with two things. First is indentation. You need to be consistant - consistant indentation helps so much with readability that I will never stop harping on it. You don't need to necessarily use my indentation style, but you do need to use some indentation style, and you need to use it consistantly. One of the best ways to do this, IMO, is to find a well-publicised style and adopt it. This is because you will always have something to refer to when you're unsure of how to indent a given problem.

      The second change is to add use strict. The error messages you're getting are telling you something. One thing it is telling you is that you declared an array @items, but then used the array @item everywhere else. In other words, a typo. In general, typos can lead to incorrect results when you end up using a brand-new global array when you intended to re-use an existing lexically-scoped array instead. In this particular case, it wasn't causing you any actual problems because all of your actual usage of @item was consistant with the sole exception of your declaration. But they have caught problems like that for me, so I continue to ensure all my code, and that of those who work for me, are strict-safe.

      Without further adieu, I present the slightly changed code:

      Note that there are a lot more "my"s in there. I suggest that you adopt this and work from here in the future as it will help you keep an eye on scope and global variables and, most importantly, typos.

      Now, to your other questions. First, subroutines. Unless that's part of the assignment, I suspect that you shouldn't worry about it too much yet. Until you get down concepts such as variable scope, this may not be an assignment dealing with subroutines. Especially with multiple hashes - to pass them around, you need other concepts such as references. And, in this case, I would be using hashes that contained other hashes rather than having a %qty hash and a %price hash (and even the @items array). And then it would be really easy to pass around and stuff. But until you get there, well, don't cross more than one bridge at a time.

      As for your if/loop. If statements don't loop - they branch. And only in one direction: down. What you want is a loop inside your loop. Again, as this is homework, I'm going to give you some pointers, not actual code. So here is what you have:

      print "Would you like to add another item? - Y or N\n"; chomp ($continue = <STDIN>);
      And this is sort-of what you want to have:
      $continue = some invalid value; while ($continue is not a valid value) { print out the prompt; chomp ($continue = <STDIN>); # unchanged. }
      Hopefully that helps you get this part down.

      Good luck,

      PS - new questions can go in new threads, as this has departed significantly from the original question, and will likely see a larger audience. Keep up the honesty on the homework issue ;-) That said, use your judgement as to whether you're asking new questions or not.

        You have given great advice and I really thank you. I am ready to submit my assignment; however you get 40 points for turning that foreach loop into a subroutine. Everytime I try the script with the foreach loop in a subroutine I get errors (uninitialized value errors).

        The assignment is worth 200 points. Some points are for coding style. When you say be consistent with the style do you mean that you indent a certain amount of spaces every time for a while, for, foreach, etc... function? I tried to stay consistent.

        I just wanted to thank you for your guidance. Now the class is back to the O Reilly book and homework at the end of the chapters. The final is a huge ordeal as it you have to write a unix adminsitration script (add a new user, check to see if the name exists, generate a random password using the username, etc...) - I hope the O Reilly book can assist with the writing of this script!

        Thank you Tanktalus

        Sierra