Your skill will accomplish what the force of many cannot |
|
PerlMonks |
Re: Print the line with the largest number from standard inputby roboticus (Chancellor) |
on Jul 22, 2019 at 19:08 UTC ( [id://11103159]=note: print w/replies, xml ) | Need Help?? |
Sorry for the length of this thing, it's one of my occasional ramble-on nodes. Essentially I'm running and fixing the code incrementally with commentary. If you want to see it in its excruciating detail .... The first thing I do when programming perl is to add the lines:
to the top of my scripts. It helps you avoid many common errors. When I did so and ran your code, it said:
It's a bunch of complaints about no variable declarations. So I then added variable declarations to the script, like so:
Running it again gave the result:
Ah, I declared the array @input. But the code is also using the scalar variable $input although it's never assigned a value. So the first error I see in your code is that you're mixing up some variables. Since your code is pretty simple, it's relatively obvious that what you really wanted is to use @input instead of trying to convert the unused scalar variable $input into a list. So a quick fix is to change @$input to @input at the end of the line containing sort. Running it again gives:
This is obviously not what you want. Looking at the code, it's pretty simple to see why: You're *always* printing $line for every iteration of the loop. That'll never work, since you want only the line with the greatest value in it. From the code you've got, it seems that you're collecting all the numbers into @input and then sorting them. That looks like a good start. But you need to do a couple of things:
So we'll add that to your script like this:
When we run it, we get the result:
Hmmm ... we have two problems. First, we're printing the wrong line. Obviously 18 is less than 2019 so why are we printing that line and not printing the line containing 2019? Secondly, why are we getting the "Use of uninitialized value" warning? We need to figure out what the program is "thinking", so we'll add some debugging print statements to show what values the code is looking at, like this:
Now, when we run the code, we get this:
OK, for the first line the program thinks the largest number is 18. That looks just fine. For the next line, though, the code thinks that the largest number is 1. That's clearly wrong! The sort function is sorting the numbers such that the smallest number is first and the largest number is last. There are several ways we could handle this:
The other thing we see is that the "Use of uninitialized value" comes from the blank line at the end. While you could just notice that there's a blank line and ignore it, that's the wrong way to fix it in this case. If you look a little more carefully, the reason for the message is that there are *no* numbers found on that line, which could be normal for your data. So rather than just ignoring a blank line, we'll ignore any line that doesn't have any numbers in it. (Note: You'll notice that we now get the "Use of uninitialized value" twice instead of once. That's to be expected as one of our debug print statements tries to print the value that doesn't exist.) So we'll make a couple changes to the code, and we get:
When we run it, the results look better:
OK, this is much better. We're printing the line with 2019 in it, and we got rid of one of the "use of uninitialized value" lines. We can take out our debugging statements now that they've done their job, and run it again. After doing so, we get:
OK, now *that's* much better. But there's still a problem. We're printing out too many lines! We only wanted to print out the line with 2019, but we got the line with 18 in it too. The problem is that we're trying to decide whether to print the line too soon. We can't decide to print any particular line until we scan through the entire file, because we never know if a later line will contain a larger number. To solve that problem, we'll add another history variable to hold the contents of the line that contains the largest number so far. Then only after processing the entire file will we bother to print the line containing the largest number:
When we run it this time, we get the result:
When learning how to program, you eventually develop a feel for what your program is actually doing. You'll get that feel by running your code under the debugger and/or by adding print statements to tell you what the program actually sees. Even after 30 years of programming, I'll still add debug statements to my code to ensure that my understanding of what the code is doing is correct. Using the debugger is a valuable skill and will help you when your code and/or data gets complicated. You should learn how to use the debugger if you want to learn how to program well. For simple things, print statements are just fine. If you want to see an example of using the debugger, check out this node I did for someone a while ago. ...roboticus When your only tool is a hammer, all problems look like your thumb.
In Section
Seekers of Perl Wisdom
|
|