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

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

Replies are listed 'Best First'.
Re^7: seeking advice on loops
by Tanktalus (Canon) on Oct 10, 2005 at 22:43 UTC

    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

        So, the question is ... what is it that you're trying, what are the exact error messages you're getting, and, if possible, what do you think the problem is? (I would suggest this going into a new thread at this point - almost no one but me will read your response to this at this point because of the high number associated with the "Re" in the subject line ;-})

        As to your style question: by consistancy, I mean that inside a single block, each line should line up on the left. Don't indent a print statement by 2 spaces, and then the following statement indent by 4. And then a few lines later, go back to only 2 spaces. Each block should indent by the same amount so that similarly-indented lines of code should be buried in similarly-deep blocks. Bad:

        if ($something) { print "here\n"; $count++; call_something(); print "here2\n"; get_input(); }
        Good:
        if ($something) { print "here\n"; $count++; call_something(); print "here2\n"; get_input(); }
        Hope that helps.