Re: returning hashes, and arrays
Stuart White wrote: Here's 25 lines of sample input: -- Spurs 94, Suns 82 4/29/2003 SBC Center, San Antonio, TX Officials: #16 Ted Bernhardt , #33 Sean Corbin , #15 Bennett Salvatore 1st Period ... (11:23) [SAN 2-0] Bowen Jump Shot: Made (2 PTS) Assist: Parker (1 AST) (11:10) [PHX] Marbury Jump Shot: Missed ... Looks like a major task of parsing here. More than that, it branches into AI, since it requires major sensitivity to contextual cues. The big picture is creating a box score. the categories are points, offensive rebounds, defensive ... I plan on getting to the end by writing small programs that parse the lines for the different categories. There is a better way. Writing separate programs requires shelling out to communicate between them. Very inflexible. I would recommend instead that you learn about the use of subroutines. As you take on complex tasks, you will benefit by writing compact, mofular subroutines to handle processes at any particular level of abstraction. To use subroutines well, you of course must be comfortable with the use of references. With these two tools available, you will be well-equipped to taake on object-oriented programming. I see this as the point where you would want to branch out to multi-file programming. I have the feeling that by the time you have a good solution to this problem, you may need to develop some representative objects, since it is not a trivial task. Then, I plan on putting them all together, either as includes C includes, Perl uses into one main, No main in Perl, unless you define and explicitly call it. or cutting and pasting them into one file. I expect to use a lot of regular expressions to parse the files, and some hashes, arrays, and perhaps a bit more complex data structures like ArraysOfArrays, or HashesOfHashes, to store the information. Please slow down a bit here. Not that all these tools may not be called upon along the way, but this point is first to define the needed outcome, and then choose the tools needed at any stage along the way. The sample data you posted included a number of different types of information, each of which probably calls for special handling. Have you enumerated the specific types of information contained? You will probably need to do so. A well-named set of subroutines can make the task much easier. Something like-- my $box_score_ref = PlayByPlay-new('Lakers', 'Suns', 'Phoenix', '01/25/2004'); open PLAYS, 'play_by_play.txt' or die couldn't open raw report: $!; while (my $line = PLAYS) { if (my $shot = shot_taken($line)) { record_shot($shot); } elsif (my $penalty = penalty_on_play($line)) { reord_penalty($penalty); } eslif ... which will give you a great deal of lexibility in handling the differnt kinds of data and formats that these reports are throwing at you. Does that help? You tell us. Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
Looks like a major task of parsing here. Yup, I think it is going to be. More than that, it branches into AI, since it requires major sensitivity to contextual cues. That I don't know. There is a better way. Writing separate programs requires shelling out to communicate between them. Very inflexible. I would recommend instead that you learn about the use of subroutines. Well, I'd like to use them as subroutines in one big program, but to get there, I'd have to start with the smaller tasks of parsing for scores, parsing for assists, parsing for rebounds etc. Then, I'd put them all together, line them up and call them one after the other. As you take on complex tasks, you will benefit by writing compact, mofular subroutines to handle processes at any particular level of abstraction. I expect so. I'd love to be able to write a subroutine that I use over and over again for different programs. Right now, I'm at the level of writing a subroutine that is useful for a very specific task, and nothing else. I'm aware of this, and love to get to that point, but that's going to take time, perhaps even more time than I have, as this is a hobby. I struggle with this because I majored in Political Science... :) To use subroutines well, you of course must be comfortable with the use of references. That makes sense. With these two tools available, you will be well-equipped to taake on object-oriented programming. I see this as the point where you would want to branch out to multi-file programming. I have the feeling that by the time you have a good solution to this problem, you may need to develop some representative objects, since it is not a trivial task. I recognize it's not trivial to me. I always thought that an experienced Perl programmer could knock it out in about a week. Then, I plan on putting them all together, either as includes C includes, Perl uses gotcha. Same idea though, right? But I understand there's a value in getting the terminology correct. into one main, No main in Perl, unless you define and explicitly call it. I know this too, which makes it difficult to talk like there is one. It's just how I think of programming as that's how I was first taught. or cutting and pasting them into one file. I expect to use a lot of regular expressions to parse the files, and some hashes, arrays, and perhaps a bit more complex data structures like ArraysOfArrays, or HashesOfHashes, to store the information. Please slow down a bit here. Not that all these tools may not be called upon along the way, but this point is first to define the needed outcome, and then choose the tools needed at any stage along the way. The sample data you posted included a number of different types of information, each of which probably calls for special handling. I don't know which of these, if any of these, data structures I might need to use. I'm just presupposing. Have you enumerated the specific types of information contained? You will probably need to do so. Do you mean the type of information I want out of this? If so, then yes, this was one of the very first things I did. A well-named set of subroutines can make the task much easier. Something like-- snip I agree with that. Does that help? You tell us. yup. I'm trying to decide if I want to take a break from this specific task and get into the examples of subroutines and references in my book. On the one hand, that should give me a much better grip on them, but on the other, that's time spent that I could be using to work on my own program. I could be taking a program that I know pretty well now, and tweak it to include references and subroutines, like I've been trying to do. All of you are being very helpful though, and I'm appreciative of that. Thanks. __ Do you Yahoo!? Yahoo! Finance Tax Center - File online. File on time. http://taxes.yahoo.com/filing.html -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
Stuart White wrote: I've tried this the only way I know how, which is to declare the subs with the number of arguments they are to take, and I believe the type of argument they are to output (like you might see in a C program), and then created my variables within the sub. Two things happened, when I couldn't get one of them to work and asked for help here, The problem here is that you are working with different syntax. Perl prototypes have a very specific meaning and purpose that is different than that used in C. I definitely enjoy--and prefer--using prototypes when working with C. In fact, I really don't have choice, but I find them useful. In Perl, you do the work elsewhere. A well-constructed first line or two in a subroutine can serve much the same purpose as a function signature: sub do_something { my $object = shift; my ($this_var, $that_var, $thuther_var) = @_; ... Since Perl is an untyped language, you are not going to get much more information from a header anyway, so the key is in choosing good, evocative names. It is very important, when working with any language, to take it on its own terms. Good practice for law, too. You could try looking at Perl subs as having a built-in prototype list sub (list @argv); This does shift the responsibility for validation into the implementation. You just have to work with that. Keeping your function definitions compact will help. If you can see all affected lines of the scope in one screen, it is much more straghtforward to evaluate what is going on throughout the function. That is another reason to avoid globals, and take references to any data you may have to modify as arguments to your subs. Sounds like this is frustrating for you, I know, but stick with it. Perl subs and scoping do have a logic of their own. Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
Stuart White wrote: You might want to depend on the documentation that comes with perl more than the book you are using. 'perlfunc' has a listing of almost all the the functions you'll see here. Perldoc.com has handy html documentation for the major versions of perl. 'Perlsub' does a better, deeper job than me with subroutines. Yeah, I had this problem before. Someone told me to go to STart-Program Files-ActiveSTate 5.8- Documentation This gave me what I find at the manpages, not perldoc. It was laid out well, but it was confusing. Same thing. The perldoc utility serves up man-pages in a system-independent manner using plain text. The ActiveState documentaion is the same POD converted to HTML. The only real difference that I can detect is the output format. Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
Stuart White wrote: I'm trying to decide if I want to take a break from this specific task and get into the examples of subroutines and references in my book. On the one hand, that should give me a much better grip on them, but on the other, that's time spent that I could be using to work on my own program. I could be taking a program that I know pretty well now, and tweak it to include references and subroutines, like I've been trying to do. I think it would be time well spent, presuming you have good, solid references. Getting a good grasp of the essential tools will save a great deal of time when you put your skills to work on practical projects. You do have to be ready to shift your paradigm just a bit, since perl is very much its own animal. Taken on itw own terms, though, it can be very effective and dependable. The main catch is that you have to choose that dependability, such as choosing to use strict. Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
Stuart White wrote: I'm having trouble returning a hash from a subroutine, and an array from a different subroutine. Beginning Perl said I could return a list, I can't get it to work. Must the hash and array really be a reference to the hash and array in order to return them? In brief, *Yes* You should get comfortable with this, if you have any desire to be a programmer. No matter what language you work in, power programming will largely depend on an understanding of references, and their close cousins, pointers. In not so brief, yes and no. It seems like the code should have returned a list of elements. Unfortunately, there is only one element, since you overwrite the whole array each time through the loop. I'm pretty sure the logic would have p[opulated the array other than this. It would still be quite wasteful, since this whole list would have to be recopied, where an anobynous hash would have already been packed for transit. I would really suggest that you overcome whatever resistance you have to working with references. If you approach them fresh, they are really rather straightforward. Put a little energy into getting over this hump in the learning curve, and you can reap benefits in all your programming efforts. Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
BTW, avoid using $a and $b for variable names, even in examples. They have a special meaning in the perl 'sort' function. Good to know. I wasn't really aware. I just used them here to shorten the name of the variable. : This is all making sense, sort of like when shift : operates on $_. Yes, but 'shift' operates on @_ not $_. That would make sense because 'shift' is shifting a list (or array). Perhaps you are thinking of 'split'. It operates on $_ by default. My mistake. I meant something like this: if (my $match =~ /'Shot'/) { my @matchedLines = unshift; ) however, I'd really use push there, but unshift would work as well I believe. I was thinking of shift and how it relates to push. I understand shift is an array function, not a scalar, but, as usual, I've failed to be clear. snip : So when Cozens uses something like: : sub link($$); : if he were passing arrays, he'd do: : sub link(@@); : and hashes: : sub link(%%); : Is that correct? That's what it seems you are : saying. Yes, that seems correct. Again, though, it seems too limiting to me. This example fails because perl doesn't see the return of foo() as two scalars. I stared at this code below for about 10 minutes before I understood what was going on, why one failed and one worked...my response to that would be, of course! you're passing literals, not scalars to anchor(), but you're prototyping anchor() to receive literals. See, if I saw some code where anchor() was used twice, once where it received scalars, and another when it received literals or hashes, or arrays, I'd be so confused. sub anchor($$); print anchor( '/perl/', 'Learning Perl' ); # works print anchor( foo() ); # fails sub anchor($$) { my( $href, $name ) = @_; return qq(a href=$href$name/a); } sub foo() { return( '/perl/', 'Learning Perl' ); } Note: It turns out that 'link' is a core function, so I changed it to anchor() for testing. gotcha. thanks for the note. We would need this use anchor() as is: my( $href, $name ) = foo(); print anchor( $href, $name ); where $href = /'perl'/ and $name = /'Learning Perl'/, right? You may find that warm and comfy. ...like a teddy bear from FAO Schwartz. I find it a pain in the ass. TIMTOWTDI. I never saw the benefit of passing literals, which might explain it. How about a quote from 'perltooc' by Tom Christiansen: Perl believes in individual responsibility rather than mandated control. Perl respects you enough to let you choose your own preferred level of pain, or of pleasure. Perl believes that you are creative, intelligent, and capable of making your own decisions- -and fully expects you to take complete responsibility for your own actions. I've read this before. I believe I read it the first few days, this, and the horribly complex-looking syntax nearly turned me away from perl. If I could have done all my fun programming ideas in C, I'd never have touched a perl book...Oddly enough, substitute 'C' for 'Perl' in the quote above, and it sounds like the mantra from my first programming book, and professor. But that's an aside. : I agree. However, that shouldn't be the goal : (in perl) for a beginner. It is possible, but it : requires the knowledge you'll obtain by using some : data structures. : : I'm not sure what you're saying here. You could achieve your goal of programming with only subroutines by using objects. In perl an object is (normally) a blessed reference to a data structure. IMO, the more you already understand data structures in perl the easier it will be to move toward objects in perl. Gotcha. This makes sense. snip I had the same problem with the documentation. It is easier now, but the first few months were very frustrating. I hate the way perlfunc is laid out. I added an alphabetical function listing to it, just for looking up unfamiliar functions I find in programs. Heck, if I could copy and paste from my DOS window to Word, then, I'd do that for every time I had to look up something on perldoc. I'm just flabbergasted that perldoc isn't on the web... Oh, sure delete the one below! Make /me/ go look it up! :) In that script I am passing the file handle DATA to a subroutine. If I have strict 'subs' turned off, I could use this and everything would be fine: I think I understand now. I'm going to go and see if I can't apply some of this to my program. It does everything I want now, I just want to clean it up and get it into separate subroutines. thanks, -stu __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
Stuart White [EMAIL PROTECTED] wrote: : : sub anchor($$); : : print anchor( '/perl/', 'Learning Perl' ); # works : print anchor( foo() ); # fails : : sub anchor($$) { : my( $href, $name ) = @_; : return qq(a href=$href$name/a); : } : : sub foo() { : return( '/perl/', 'Learning Perl' ); : } : : I stared at this code for about 10 minutes before I : understood what was going on, why one failed and one : worked... my response to that would be, of course! : You're passing literals, not scalars to anchor(), This is perl. Literals are scalars. : but you're prototyping anchor() to receive literals. No. I'm prototyping anchor() to receive two scalar values. Numbers, strings, and references are all valid scalars in perl. Perl prototyping does not distinguish between variables and literals. : See, if I saw some code where anchor() was used : twice, once where it received scalars, and another : when it received literals or hashes, or arrays, I'd : be so confused. That's a problem when thinking in one language while programming in another. Sometimes you have to forget the C you know. : I never saw the benefit of passing literals, which : might explain it. As for as perl prototyping is concerned literals and scalar variables are interchangeable. Perl is not a subset of C. It is a whole new adventure. HTH, Charles K. Clarkson -- Mobile Homes Specialist 254 968-8328 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
Got it. Thanks. --- Charles K. Clarkson [EMAIL PROTECTED] wrote: Stuart White [EMAIL PROTECTED] wrote: : : sub anchor($$); : : print anchor( '/perl/', 'Learning Perl' ); # works : print anchor( foo() ); # fails : : sub anchor($$) { : my( $href, $name ) = @_; : return qq(a href=$href$name/a); : } : : sub foo() { : return( '/perl/', 'Learning Perl' ); : } : : I stared at this code for about 10 minutes before I : understood what was going on, why one failed and one : worked... my response to that would be, of course! : You're passing literals, not scalars to anchor(), This is perl. Literals are scalars. : but you're prototyping anchor() to receive literals. No. I'm prototyping anchor() to receive two scalar values. Numbers, strings, and references are all valid scalars in perl. Perl prototyping does not distinguish between variables and literals. : See, if I saw some code where anchor() was used : twice, once where it received scalars, and another : when it received literals or hashes, or arrays, I'd : be so confused. That's a problem when thinking in one language while programming in another. Sometimes you have to forget the C you know. : I never saw the benefit of passing literals, which : might explain it. As for as perl prototyping is concerned literals and scalar variables are interchangeable. Perl is not a subset of C. It is a whole new adventure. HTH, Charles K. Clarkson -- Mobile Homes Specialist 254 968-8328 __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
When writing a subroutine, think of it as a miniature program. Something is passed in, processed, and output. Some subs only do one or two of those, but many do all three. Try not to process anything that is not local to the sub. That's how I think of them. I'd prefer to be able to pass in a value, have the sub take that value into it's own variable, process it, and then spit it back out into the value back in the main or parent(in the case that there is a sub within a sub) program. I've tried this the only way I know how, which is to declare the subs with the number of arguments they are to take, and I believe the type of argument they are to output (like you might see in a C program), and then created my variables within the sub. Two things happened, when I couldn't get one of them to work and asked for help here, I felt like I got flamed from a few people because I was declaring my subroutines with the number of arguments. I was told I didn't have to so why bother. I did it for two reasons, the only intro programming class I took taught in C, that's how it was taught, and I happened to like that style because of the organization, AND, in 'Beginning Perl' the author writes about doing it that way. This was about 8 mos ago before I had to stop working on this to study for the LSAT. I still think of subs that way, but think that perhaps Perl is not so much like C, and I get the feeling that the Perl community doesn't like the structure of C and avoids it, sometimes passing on that sentiment to others. (I recognize I ranted and went off on a tangent a bit, I hope that's not too rude.) In ParseLineForHomeAndVisitors(), $_ is not local to the sub, neither is @teams. It would be better to pass that value in: See, it doesn't look like you're passing anything in here. If I were to write it, I'd write it like this: #sub protype declaration #this would be up at the top, #before I even declared any variables ParseLineForHomeAndVisitors($); sub ParseLineForHomeAndVisitors($line) { my $line = shift; my @teams = ( $line =~ /([[:alpha:]]+)/g ); return @teams; } which may or may not work, but it seems to follow the structure Cozens talks about in his book, 'beginning perl', ch 8, page 254. Perhaps this is just an internal battle with me not understanding the syntax of perl subroutines, and not wanting to relinquish the clarity of a C program. I left out the validation because the sub isn't named ParseLineForHomeAndVisitorsIfLineIsValid() and because, IMO, that's too much work for one sub. For the validation I'd agree with that. I'll give a hint: Don't use a regex. Read three slides from M-J Dominus: http://perl.plover.com/yak/hw2/samples/slide007.html Thanks. will do. : I tried the same thing with my hash: : : CreateAbbrevAndNicknamesHash(); : : and here's the sub: : sub CreateAbbrevAndNicknamesHash() : { : my %AbbrevAndNicknames; : %AbbrevAndNicknames = ( : IND= Pacers, : . : . : . : ); : : : } The big question here is: Why a subroutine? Style. If I had my druthers, I'd write a program with nothing but subroutines in the main program. For example, to program a robot to pour a glass of milk: GoToIcebox(); OpenDoor(); LocateMilk(); GrabMilk(); RemoveMilkFromIcebox(); CloseDoor(); MoveToCounter(); PutMilkOnCounter(); ... (I think the point has been made) :) PourMilkInGlass(); And then below, I'd have a section called sub definitions, where I'd define all those subs, and maybe others that made up those subs. Writing like this is easier on my eyes and tells me and someone else (given my subs have descriptive names) a very good idea of what I want to do. I write subs for printing out a few lines of intro instructions. It just makes sense to me. So that's why a sub. If you want to create a hash, create a hash: my %AbbrevAndNicknames = ( IND = 'Pacers', NJN = 'Nets', DET = 'Pistons', snip PHX = 'Suns', ); I don't see the point of the subroutine. If you want to return a hash from a subroutine, use 'return'. Note that foo() actually returns a list (or is it an array?). We decide to stuff the result into a hash. I tried using return. It didn't work. I thought maybe it was because I was trying to return a hash, or trying to return the hash to a hash and not a scalar (which would have been zero use to me). #!/usr/bin/perl use strict; use warnings; use Data::Dumper 'Dumper'; my %foo_hash = foo(); print Dumper \%foo_hash; sub foo { return ( I'll try it this way. I used return at the end of the sub, after the ; but before the }. Thanks. SEA = 'Supersonics', LAC = 'Clippers', GSW = 'Warriors', PHX = 'Suns',
RE: returning hashes, and arrays
--- Charles K. Clarkson [EMAIL PROTECTED] wrote: Stuart White [EMAIL PROTECTED] wrote: : : I figured the small snippets, how to : print an array, how to split a string etc., was : better as it was more focused, and would apply : to not just the one example. That's a great way to break the program down, but over the years I have found that many beginners are asking the wrong question. Supplying a good answer to the wrong question doesn't usually help much. With just a bit more information, I can tell whether the question is the right one and whether I should invest my time in it or not. Sure, I agree with that. For example, here's your parsing sub: sub ParseLineForHomeAndVisitors() { if ($_ =~/Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers|Celtics| Pacers|Pistons|Wizards|Warriors|Bulls|Hawks|Raptors|Magic| Heat|Kings|Rockets|Nuggets|Grizzlies|Jazz|Knicks|Nets| Supersonics|'Trail Blazers'|Bucks|Timberwolves|Hornets| Sixers|Bobcats)/) { @teams = /([[:alpha:]]+)/g; } return (@teams); } The 'if' statement is doing 3 suspicious things. One, it is capturing the match. Two, I suspect 'Trail Blazers' in single quotes will never be found. And it is not obvious what happens if there is no match. It looks like @teams is a global variable, but since that is a Bad Thing, I would hope you weren't using it. 1)Well, I want it to capture the match. 2)Are you suspicious because Trail Blazers is in single quotes, or because it might be 'Trail' or 'Blazers'? If it's the latter, no need for suspicion because it will only show up as 'Trail Blazers.' If it is the former, then there is something I'm missing in my understanding of single and double quotes. 3)Well, I've been taught not to use global variables, unless I have to, and I was then taught that I should not have to, not at the level I was programming at, so it's not my intention to use a global variable. What is not shown in the code above is where I declare my @teams; From my understanding of Perl, that makes the variable local, right? More importantly, (IMO) the sub probably shouldn't be doing the line validation. That should be done to determine if this sub should be called. I think I see what you mean, but I think that the purpose of the sub IS to find that line, and extract the teams from it and then put them into an array where I can then call them as scalars, ($teams[0] and $teams[1]). I could write a nice long answer about this sub, but I'd probably be answering the wrong question. Entirely possible. I try my best to write clearly what I know or think I know, what I want the code to do, what I think the code is doing, and what my end goal is, but sometimes, I don't include the end goal, and sometimes I get tired of detail. : Here's 25 lines of sample input: : -- : Spurs 94, Suns 82 : 4/29/2003 SBC Center, San Antonio, TX : Officials: #16 Ted Bernhardt , #33 Sean Corbin , #15 : Bennett Salvatore : 1st Period : (12:00) Jump Ball Robinson vs Williams : (11:41) [PHX] Marion Turnaround Jump: Missed [snip] : Thanks. Is each input example like this.? Yes, in form. Not literally. For example, line one might be in a different file: Mavericks 119, Heat 99 Is there a chance that a second line like Spurs 94, Suns 82 will show up? Not in the same file. That line shows up only once, and only at the top. There might be one or two insignificant lines above that one in all the files, but, as I've no use for those lines, I didn't paste them over here. Or will it be in a different dataset (file, recordset, etc.)? There certainly could be one, and only one other file that looks exactly like that, as in the same score, and the same order of teams. However, the likelihood of that happening is very small. It is likely however to have this line: Spurs 120, Suns 100 or Spurs 83, Suns 77 and in fact, there will be another file that has the teams in the same order, but the scores are likely to be different. However, in any one file, there will only be ONE line that looks like that. The reason I ask Is that there is probably a better way to pick this line out of the file than that it contains team names. For example, it seems to be the only line that will match /[[:alpha:]]+\s+[[:digit:]]+,/. It also seems to be the first line. Is it always the first line? Once I've extracted the two lines of insignificance, then yes, it will always be the first line. And I agree, there ought to be an easier way. The reason I wrote this particular sub was because at the end of the program, for a test,(and eventually not a test, but a significant part of the program) I wanted to print out the rosters of the two teams, which I've done, but I also wanted to print the teams nicknames, and not have to hardcode that into every program. this entailed linking the nicknames to the abbreviations (SAN, PHX) because, as you'll
RE: returning hashes, and arrays
In the last 6 months I have come to feel that understanding Perl contexts is the most important and difficult thing in the language, so your statement and question very important I don't see the point of the subroutine. If you want to return a hash from a subroutine, use 'return'. Note that foo() actually returns a list (or is it an array?). We decide to stuff the result into a hash. It returns a list because of exactly what you said in your last sentence, We decide to stuff the result..., so it is a list until you have decided what to stuff it into, which could be a 'list' of scalars ($scalara, $scalarb) = foo(); array slice @array[ 3 .. 4] = foo(); hash slice @hash{ 'key1', 'key2' } = foo(); arguments to a loop foreach ( foo() ); arguments to another sub bar( foo() ); or just an 'array' @array = foo(); etc. A square is a rectangle, but a rectangle is not necessarily a square. An array is a list, but a list is not necessarily an array. http://danconia.org -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
Stuart White [mailto:[EMAIL PROTECTED] : : When writing a subroutine, think of it as a miniature : program. Something is passed in, processed, and output. Some : subs only do one or two of those, but many do all three. Try : not to process anything that is not local to the sub. : : That's how I think of them. I'd prefer to be able to pass in a : value, have the sub take that value into it's own variable, : process it, and then spit it back out into the value back in the : main or parent (in the case that there is a sub within a sub) : program. I've tried this the only way I know how, which is to : declare the subs with the number of arguments they are to take, : and I believe the type of argument they are to output (like you : might see in a C program), and then created my variables within : the sub. Two things happened, when I couldn't get one of them : to work and asked for help here, I felt like I got flamed from a : few people because I was declaring my subroutines with the : number of arguments. I was told I didn't have to so why bother. I'm sorry about that. I didn't mean to flame you. It just seemed like you were taking the long way around to solve the problem. : I did it for two reasons, the only intro programming class I : took taught in C, that's how it was taught, and I happened to : like that style because of the organization, AND, in : 'Beginning Perl' the author writes about doing it that way. This : was about 8 mos ago before I had to stop working on this to : study for the LSAT. I still think of subs that way, but think : that perhaps Perl is not so much like C, and I get the feeling : that the Perl community doesn't like the structure of C and : avoids it, sometimes passing on that sentiment to others. That's funny. When I started reading the documentation a few years ago, I got the distinct impression that only programmers with a background in C were being invited to the perl party. I even complained about it on the another beginner email list. : (I recognize I ranted and went off on a tangent a bit, I hope : that's not too rude.) No. I'm so glad you said all that. It explains a lot. If I had known this when you first mentioned prototypes, I could have written a more useful reply. : In ParseLineForHomeAndVisitors(), $_ is not local to the sub, : neither is @teams. It would be better to pass that value in: : : : See, it doesn't look like you're passing anything in here. If I : were to write it, I'd write it like this: : #sub protype declaration #this would be up at the top, : #before I even declared any variables : ParseLineForHomeAndVisitors($); : : sub ParseLineForHomeAndVisitors($line) { : my $line = shift; : my @teams = ( $line =~ /([[:alpha:]]+)/g ); : return @teams; : } : : which may or may not work, but it seems to follow the : structure Cozens talks about in his book, 'beginning : perl', ch 8, page 254. : Perhaps this is just an internal battle with me not : understanding the syntax of perl subroutines, and not : wanting to relinquish the clarity of a C program. Okay. In perl everything is passed into the sub with a special array called @_. Let's call a subroutine named link(). (I'm going to use list and array interchangeably here. They're not really the same though.) print link( '/perl/', 'Learning Perl' ); Behind the scenes, perl creates a list of the two arguments '/perl/' and 'Learning Perl' and sets it equal to @_. It then passes control to link(). Inside link() we need to access @_ to get to the arguments. What is declared on the subroutine declaration line is not use by perl to transfer subroutine arguments. It is only used for type checking. Let's write link(): sub link { my( $href, $name ) = @_; return qq(a href=$href$name/a); } It is pretty obvious how the we accessed @_ here, but in ParseLineForHomeAndVisitors() we have this: sub ParseLineForHomeAndVisitors($line) { my $line = shift; my @teams = ( $line =~ /([[:alpha:]]+)/g ); return @teams; } The second line is accessing @_. 'shift' operates on @_ by default, so my $line = shift; is shorthand for: my $line = shift @_; In perl, declaring subs at the top of the script is necessary when using prototypes. Prototypes in perl do not work the way you are using them. They do not declare a variable. They restrain the type of values which can be passed to a subroutine. Perl prototyping handles this type checking for the programmer, but it still uses @_ to pass arguments for the sub. I have always found prototypes too restrictive. I understand why you are using them, but I still think life will be easier if you abandon them. : : I tried the same thing with my hash: : : : : CreateAbbrevAndNicknamesHash(); : : : : and here's the sub: : : sub CreateAbbrevAndNicknamesHash() : : { : : my %AbbrevAndNicknames; : : %AbbrevAndNicknames = ( : :IND= Pacers, : : . : : . : :
RE: returning hashes, and arrays
I'm sorry about that. I didn't mean to flame you. It just seemed like you were taking the long way around to solve the problem. It was a year ago. I don't remember who it was, and it's not a big deal anymore. That's funny. When I started reading the documentation a few years ago, I got the distinct impression that only programmers with a background in C were being invited to the perl party. I even complained about it on the another beginner email list. My background in C extends to pointers -- I'm still the novice there. :) snip Okay. In perl everything is passed into the sub with a special array called @_. Let's call a subroutine named link(). (I'm going to use list and array interchangeably here. They're not really the same though.) print link( '/perl/', 'Learning Perl' ); Behind the scenes, perl creates a list of the two arguments '/perl/' and 'Learning Perl' and sets it equal to @_. It then passes control to link(). Before we go on, what if you had $a='/perl/'; $b = 'Learning Perl'; then did: print link($a, $b); -that's how I'd pass information, as variables, not literals. Does this change what comes next? Inside link() we need to access @_ to get to the arguments. What is declared on the subroutine declaration line is not use by perl to transfer subroutine arguments. It is only used for type checking. Let's write link(): sub link { my( $href, $name ) = @_; return qq(a href=$href$name/a); } It is pretty obvious how the we accessed @_ here, but in ParseLineForHomeAndVisitors() we have this: sub ParseLineForHomeAndVisitors($line) { my $line = shift; my @teams = ( $line =~ /([[:alpha:]]+)/g ); return @teams; } The second line is accessing @_. 'shift' operates on @_ by default, so This is all making sense, sort of like when shift operates on $_. my $line = shift; is shorthand for: my $line = shift @_; In perl, declaring subs at the top of the script is necessary when using prototypes. It's not necessary otherwise? Like: #sub declarations sub ParseLineForHomeAndVisitors; sub link; That's how I do it, whether or not there is something I want to pass or return with the sub. Prototypes in perl do not work the way you are using them. They do not declare a variable. They restrain the type of values which can be passed to a subroutine. So when Cozens uses something like: sub link($$); if he were passing arrays, he'd do: sub link(@@); and hashes: sub link(%%); Is that correct? That's what it seems you are saying. Perl prototyping handles this type checking for the programmer, but it still uses @_ to pass arguments for the sub. I have always found prototypes too restrictive. I understand why you are using them, but I still think life will be easier if you abandon them. Restrictive, but protective. I find perl to allow too much freedom. And, as a novice programmer, I'd rather be as clear as day. But I see your point. snip I agree. However, that shouldn't be the goal (in perl) for a beginner. It is possible, but it requires the knowledge you'll obtain by using some data structures. I'm not sure what you're saying here. : And then below, I'd have a section called sub definitions, where : I'd define all those subs, and maybe others that made up those : subs. Writing like this is easier on my eyes and tells me and : someone else (given my subs have descriptive names) a very good : idea of what I want to do. I write subs for printing out a few : lines of intro instructions. It just makes sense to me. So : that's why a sub. In perl, one problem with using a sub this way is that it forces the use of global variables. If %AbbrevAndNicknames has not been declared above the subroutine, how else will you pass it around the script? Hmm, not sure. I used to be able to do it in C, without globals, but I haven't gotten that far in perl. snip You might want to depend on the documentation that comes with perl more than the book you are using. 'perlfunc' has a listing of almost all the the functions you'll see here. Perldoc.com has handy html documentation for the major versions of perl. 'Perlsub' does a better, deeper job than me with subroutines. Yeah, I had this problem before. Someone told me to go to STart-Program Files-ActiveSTate 5.8- Documentation This gave me what I find at the manpages, not perldoc. It was laid out well, but it was confusing. Here is a small script to show typical processing of a file in perl. Instead of opening a file. I'll use the special file handle DATA, which is everything past the __END__ tag in this script. Hopefully, it will give you a basis for writing subs in perl. #!/usr/bin/perl use strict; use warnings; use Data::Dumper 'Dumper'; # @teams is at file level scope. Perl allows # it to be used
RE: returning hashes, and arrays
Stuart White [EMAIL PROTECTED] wrote: : : I'm sorry about that. I didn't mean to flame : you. It just seemed like you were taking the long : way around to solve the problem. : : It was a year ago. I don't remember who it was, and : it's not a big deal anymore. I've been here awhile and I'm pretty sure it was me. I'm glad you came back. :) : My background in C extends to pointers -- I'm still : the novice there. :) I am a complete moron when it comes to C. : Okay. In perl everything is passed into the sub : with a special array called @_. Let's call a : subroutine named link(). (I'm going to use list and : array interchangeably here. They're not really the : same though.) : : print link( '/perl/', 'Learning Perl' ); : : Behind the scenes, perl creates a list of the : two arguments : '/perl/' and 'Learning Perl' and sets it equal to : @_. It then : passes control to link(). : : : Before we go on, what if you had $a='/perl/'; $b = : 'Learning Perl'; : then did: : print link($a, $b); -that's how I'd pass : information, as variables, not literals. : Does this change what comes next? No. I used literals to shorten the example. BTW, avoid using $a and $b for variable names, even in examples. They have a special meaning in the perl 'sort' function. : This is all making sense, sort of like when shift : operates on $_. Yes, but 'shift' operates on @_ not $_. That would make sense because 'shift' is shifting a list (or array). Perhaps you are thinking of 'split'. It operates on $_ by default. : In perl, declaring subs at the top of the : script is necessary when using prototypes. : : It's not necessary otherwise? No. : Like: : #sub declarations : sub ParseLineForHomeAndVisitors; : sub link; : : That's how I do it, whether or not there is something : I want to pass or return with the sub. : Prototypes in perl do not work the way you are : using them. They do not declare a variable. They : restrain the type of values which can be passed to : a subroutine. : : So when Cozens uses something like: : sub link($$); : if he were passing arrays, he'd do: : sub link(@@); : and hashes: : sub link(%%); : Is that correct? That's what it seems you are : saying. Yes, that seems correct. Again, though, it seems too limiting to me. This example fails because perl doesn't see the return of foo() as two scalars. sub anchor($$); print anchor( '/perl/', 'Learning Perl' ); # works print anchor( foo() ); # fails sub anchor($$) { my( $href, $name ) = @_; return qq(a href=$href$name/a); } sub foo() { return( '/perl/', 'Learning Perl' ); } Note: It turns out that 'link' is a core function, so I changed it to anchor() for testing. We would need this use anchor() as is: my( $href, $name ) = foo(); print anchor( $href, $name ); You may find that warm and comfy. I find it a pain in the ass. TIMTOWTDI. : Perl prototyping handles this type checking for : the programmer, but it still uses @_ to pass : arguments for the sub. I have always found : prototypes too restrictive. I understand why you : are using them, but I still think life will be : easier if you abandon them. : : Restrictive, but protective. I find perl to allow : too much freedom. And, as a novice programmer, I'd : rather be as clear as day. But I see your point. You say tomato, I say tomato. Okay, that doesn't work in print. :) How about a quote from 'perltooc' by Tom Christiansen: Perl believes in individual responsibility rather than mandated control. Perl respects you enough to let you choose your own preferred level of pain, or of pleasure. Perl believes that you are creative, intelligent, and capable of making your own decisions- -and fully expects you to take complete responsibility for your own actions. : I agree. However, that shouldn't be the goal : (in perl) for a beginner. It is possible, but it : requires the knowledge you'll obtain by using some : data structures. : : I'm not sure what you're saying here. You could achieve your goal of programming with only subroutines by using objects. In perl an object is (normally) a blessed reference to a data structure. IMO, the more you already understand data structures in perl the easier it will be to move toward objects in perl. : : And then below, I'd have a section called sub : : definitions, where I'd define all those subs, and : : maybe others that made up those subs. Writing : : like this is easier on my eyes and tells me and : : someone else (given my subs have descriptive : : names) a very good idea of what I want to do. I : : write subs for printing out a few lines of intro : : instructions. It just makes sense to me. So : : that's why a sub. : : In perl, one problem with using a sub this way : is that it forces the use of global variables. If : %AbbrevAndNicknames has not been declared above the :
returning hashes, and arrays
I'm having trouble returning a hash from a subroutine, and an array from a different subroutine. Beginning Perl said I could return a list, I can't get it to work. Must the hash and array really be a reference to the hash and array in order to return them? Here's my subroutine: sub ParseLineForHomeAndVisitors() { if ($_ =~/(Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers|Celtics|Pacers|Pistons|Wizards|Warriors|Bulls|Hawks|Raptors|Magic|Heat|Kings|Rockets|Nuggets|Grizzlies|Jazz|Knicks|Nets|Supersonics|'Trail Blazers'|Bucks|Timberwolves|Hornets|Sixers|Bobcats)/) { @teams = /([[:alpha:]]+)/g; } return (@teams); } - And here's how I'm trying to capture the value: @teams = ParseLineForHomeAndVisitors(); I tried the same thing with my hash: CreateAbbrevAndNicknamesHash(); and here's the sub: sub CreateAbbrevAndNicknamesHash() { my %AbbrevAndNicknames; %AbbrevAndNicknames = ( IND= Pacers, NJN= Nets, DET= Pistons, NOH= Hornets, #check this MIL= Bucks, CLE= Cavaliers, BOS= Celtics, NYK= Knicks, MIA= Heat, PHI= Sixers, TOR= Raptors, ATL= Hawks, WAS= Wizards, ORL= Magic, CHI= Bulls, CHA= Bobcats, SAC= Kings, MIN= Timberwolves, SAN= Spurs, LAL= Lakers, DAL= Mavericks, MEM= Grizzlies, HOU= Rockets, DEN= Nuggets, UTA= Jazz, POR= Trail Blazers, SEA= Supersonics, LAC= Clippers, GSW= Warriors, PHX= Suns ); } --- Any suggestions? __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
AW: returning hashes, and arrays
That should work provided you're returning only on list. It is much better to use reference when passing or retrieving more than one value. For instance: Retrieve the values from a sub as refereces. ($xRef, $yRef, $zRef) = example(); # my @x = @$x; my @y = @$y; my $z = $$z; sub example { do this and that; # Return 3 values as refereces. return (\ @x, [EMAIL PROTECTED], \$z ); return \(@x, @y, $z);# Simpler } HTH Babs -Ursprüngliche Nachricht- Von: Stuart White [mailto:[EMAIL PROTECTED] Gesendet: Donnerstag, 18. März 2004 02:17 An: [EMAIL PROTECTED] Betreff: returning hashes, and arrays I'm having trouble returning a hash from a subroutine, and an array from a different subroutine. Beginning Perl said I could return a list, I can't get it to work. Must the hash and array really be a reference to the hash and array in order to return them? Here's my subroutine: sub ParseLineForHomeAndVisitors() { if ($_ =~/(Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers|Celtics|Pacers|Piston s|Wizards|Warriors|Bulls|Hawks|Raptors|Magic|Heat|Kings|Rockets|Nuggets| Grizzlies|Jazz|Knicks|Nets|Supersonics|'Trail Blazers'|Bucks|Timberwolves|Hornets|Sixers|Bobcats)/) { @teams = /([[:alpha:]]+)/g; } return (@teams); } - And here's how I'm trying to capture the value: @teams = ParseLineForHomeAndVisitors(); I tried the same thing with my hash: CreateAbbrevAndNicknamesHash(); and here's the sub: sub CreateAbbrevAndNicknamesHash() { my %AbbrevAndNicknames; %AbbrevAndNicknames = ( IND= Pacers, NJN= Nets, DET = Pistons, NOH = Hornets, #check this MIL = Bucks, CLE = Cavaliers, BOS = Celtics, NYK = Knicks, MIA = Heat, PHI = Sixers, TOR = Raptors, ATL = Hawks, WAS = Wizards, ORL = Magic, CHI = Bulls, CHA = Bobcats, SAC = Kings, MIN = Timberwolves, SAN = Spurs, LAL = Lakers, DAL = Mavericks, MEM = Grizzlies, HOU = Rockets, DEN = Nuggets, UTA = Jazz, POR= Trail Blazers, SEA = Supersonics, LAC = Clippers, GSW = Warriors, PHX = Suns ); } --- Any suggestions? __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
Stuart White [EMAIL PROTECTED] wrote: : : I'm having trouble returning a hash from a subroutine, : and an array from a different subroutine. Beginning : Perl said I could return a list, I can't get it to : work. Must the hash and array really be a reference : to the hash and array in order to return them? Stuart, I think there is an easier way to approach your solution. Is there any situation in which a line needing to be parsed will contain a team that is /not/ on your list of teams? Can you give us all the big picture? Tell us what your project is and let us help you solve that instead of these small snippets. If you can, give us a sample of the input data (about 10 or 20 lines), tell us what you expect and how you have decided to get there. We'll be able to help you get there with perl. I assume you are doing this at least partially as an exercise to learn perl and my intent is not to do the script for you, but a little more information would aid me not pushing you into the wrong direction. HTH, Charles K. Clarkson -- Mobile Homes Specialist 254 968-8328 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
--- Charles K. Clarkson [EMAIL PROTECTED] wrote: Stuart White [EMAIL PROTECTED] wrote: : : I'm having trouble returning a hash from a subroutine, : and an array from a different subroutine. Beginning : Perl said I could return a list, I can't get it to : work. Must the hash and array really be a reference : to the hash and array in order to return them? Stuart, I think there is an easier way to approach your solution. Is there any situation in which a line needing to be parsed will contain a team that is /not/ on your list of teams? No. All teams are accounted for. Can you give us all the big picture? Tell us what your project is and let us help you solve that instead of these small snippets. If you can, give us a sample of the input data (about 10 or 20 lines), tell us what you expect and how you have decided to get there. We'll be able to help you get there with perl. Ok, fair enough. I figured the small snippets, how to print an array, how to split a string etc., was better as it was more focused, and would apply to not just the one example. Here's 25 lines of sample input: -- Spurs 94, Suns 82 4/29/2003 SBC Center, San Antonio, TX Officials: #16 Ted Bernhardt , #33 Sean Corbin , #15 Bennett Salvatore 1st Period (12:00) Jump Ball Robinson vs Williams (11:41) [PHX] Marion Turnaround Jump: Missed (11:40) [SAN] Robinson Rebound (Off:0 Def:1) (11:23) [SAN 2-0] Bowen Jump Shot: Made (2 PTS) Assist: Parker (1 AST) (11:10) [PHX] Marbury Jump Shot: Missed (11:08) [PHX] Marion Rebound (Off:1 Def:0) (11:07) [PHX] Marion Jump Shot: Missed (11:05) [SAN] Robinson Rebound (Off:0 Def:2) (10:51) [SAN 4-0] Jackson Jump Shot: Made (2 PTS) Assist: Duncan (1 AST) (10:32) [PHX] Marion Turnover: Bad Pass (1 TO) (10:23) [SAN] Jackson Jump Shot: Missed Block: Hardaway (1 BLK) (10:20) [PHX] Stoudemire Rebound (Off:0 Def:1) (10:18) [PHX] Stoudemire Turnover: Lost Ball (1 TO) Steal: Jackson (1 ST) (10:09) [SAN] Duncan Turnover: Bad Pass (1 TO) (10:03) [PHX] Marbury Reverse Layup: Missed (10:00) [SAN] Duncan Rebound (Off:0 Def:1) (9:43) [SAN] Duncan Jump Shot: Missed Block: Stoudemire (1 BLK) (9:41) [SAN] Team Rebound (9:33) [SAN] Duncan Layup Shot: Missed Block: Stoudemire (2 BLK) (9:31) [SAN] Duncan Rebound (Off:1 Def:1) (9:31) [PHX] Williams Foul: Personal (1 PF) The big picture is creating a box score. the categories are points, offensive rebounds, defensive rebounds, assists, steals, turnovers, field goals attempted, field goals made, blocks and fouls. I assume you are doing this at least partially as an exercise to learn perl and my intent is not to do the script for you, but a little more information would aid me not pushing you into the wrong direction. Yes, the goal is to learn perl, and to write a program that is big enough to be challenging, interesting, and uses most, if not all of the building blocks, (or at least what I'd call building blocks: scalars, arrays, hashes, reading files, control structures, regex, subroutines, and references. Good, I'm not looking for anyone to write the program for me, as that isn't too helpful in learning. I just need some help along the way. I plan on getting to the end by writing small programs that parse the lines for the different categories. Then, I plan on putting them all together, either as includes into one main, or cutting and pasting them into one file. I expect to use a lot of regular expressions to parse the files, and some hashes, arrays, and perhaps a bit more complex data structures like ArraysOfArrays, or HashesOfHashes, to store the information. Does that help? __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: AW: returning hashes, and arrays
It helps in that it seems to confirm that I was going about it the right way. It doesn't in that I can't get it to work for me. I'll go read some more documentation. By the way, what does AW: mean? --- B. Fongo [EMAIL PROTECTED] wrote: That should work provided you're returning only on list. It is much better to use reference when passing or retrieving more than one value. For instance: Retrieve the values from a sub as refereces. ($xRef, $yRef, $zRef) = example(); # my @x = @$x; my @y = @$y; my $z = $$z; sub example { do this and that; # Return 3 values as refereces. return (\ @x, [EMAIL PROTECTED], \$z ); return \(@x, @y, $z);# Simpler } HTH Babs -Ursprüngliche Nachricht- Von: Stuart White [mailto:[EMAIL PROTECTED] Gesendet: Donnerstag, 18. März 2004 02:17 An: [EMAIL PROTECTED] Betreff: returning hashes, and arrays I'm having trouble returning a hash from a subroutine, and an array from a different subroutine. Beginning Perl said I could return a list, I can't get it to work. Must the hash and array really be a reference to the hash and array in order to return them? Here's my subroutine: sub ParseLineForHomeAndVisitors() { if ($_ =~/(Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers|Celtics|Pacers|Piston s|Wizards|Warriors|Bulls|Hawks|Raptors|Magic|Heat|Kings|Rockets|Nuggets| Grizzlies|Jazz|Knicks|Nets|Supersonics|'Trail Blazers'|Bucks|Timberwolves|Hornets|Sixers|Bobcats)/) { @teams = /([[:alpha:]]+)/g; } return (@teams); } - And here's how I'm trying to capture the value: @teams = ParseLineForHomeAndVisitors(); I tried the same thing with my hash: CreateAbbrevAndNicknamesHash(); and here's the sub: sub CreateAbbrevAndNicknamesHash() { my %AbbrevAndNicknames; %AbbrevAndNicknames = ( IND= Pacers, NJN= Nets, DET = Pistons, NOH = Hornets, #check this MIL = Bucks, CLE = Cavaliers, BOS = Celtics, NYK = Knicks, MIA = Heat, PHI = Sixers, TOR = Raptors, ATL = Hawks, WAS = Wizards, ORL = Magic, CHI = Bulls, CHA = Bobcats, SAC = Kings, MIN = Timberwolves, SAN = Spurs, LAL = Lakers, DAL = Mavericks, MEM = Grizzlies, HOU = Rockets, DEN = Nuggets, UTA = Jazz, POR= Trail Blazers, SEA = Supersonics, LAC = Clippers, GSW = Warriors, PHX = Suns ); } --- Any suggestions? __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response __ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
On 3/17/2004 9:39 PM, Stuart White wrote: Yes, the goal is to learn perl, and to write a program that is big enough to be challenging, interesting, and uses most, if not all of the building blocks, (or at least what I'd call building blocks: scalars, arrays, hashes, reading files, control structures, regex, subroutines, and references. Good, I'm not looking for anyone to write the program for me, as that isn't too helpful in learning. I just need some help along the way. I plan on getting to the end by writing small programs that parse the lines for the different categories. Then, I plan on putting them all together, either as includes into one main, or cutting and pasting them into one file. I expect to use a lot of regular expressions to parse the files, and some hashes, arrays, and perhaps a bit more complex data structures like ArraysOfArrays, or HashesOfHashes, to store the information. Does that help? FWIW, You are right on track. The way your working on smaller pieces first and then assembling them into larger pieces, overcoming one problem/task/concept at a time. You are doing everything as it should be done. One thing I might add is that it would make things easier in the long run if you write test cases as you go for each task. Read the docs in Test::Simple, Test::Tutorial, etc. and for each function/task write one or more test cases that test variances in input, and any problem you can think of that might arise. It's not critical, but perl encourages it, and it is a good habit to get into. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: returning hashes, and arrays
On 3/17/2004 8:16 PM, Stuart White wrote: I'm having trouble returning a hash from a subroutine, and an array from a different subroutine. Beginning Perl said I could return a list, I can't get it to work. Must the hash and array really be a reference to the hash and array in order to return them? Here's my subroutine: sub ParseLineForHomeAndVisitors() { if ($_ =~/(Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers|Celtics|Pacers|Pistons|Wizards|Warriors|Bulls|Hawks|Raptors|Magic|Heat|Kings|Rockets|Nuggets|Grizzlies|Jazz|Knicks|Nets|Supersonics|'Trail Blazers'|Bucks|Timberwolves|Hornets|Sixers|Bobcats)/) { @teams = /([[:alpha:]]+)/g; } return (@teams); } - And here's how I'm trying to capture the value: @teams = ParseLineForHomeAndVisitors(); What values do you get in @teams (both in the function as a return). use Data::Dumper; print Dumper([EMAIL PROTECTED]); I tried the same thing with my hash: CreateAbbrevAndNicknamesHash(); my %hash = CreateAbbrevAndNicknamesHash(); use Data::Dumper; print Dumper(\%hash); and here's the sub: sub CreateAbbrevAndNicknamesHash() { my %AbbrevAndNicknames; %AbbrevAndNicknames = ( in place of the above two lines, you can just return ( IND= Pacers, NJN= Nets, DET= Pistons, NOH= Hornets, #check this MIL= Bucks, CLE= Cavaliers, BOS= Celtics, NYK= Knicks, MIA= Heat, PHI= Sixers, TOR= Raptors, ATL= Hawks, WAS= Wizards, ORL= Magic, CHI= Bulls, CHA= Bobcats, SAC= Kings, MIN= Timberwolves, SAN= Spurs, LAL= Lakers, DAL= Mavericks, MEM= Grizzlies, HOU= Rockets, DEN= Nuggets, UTA= Jazz, POR= Trail Blazers, SEA= Supersonics, LAC= Clippers, GSW= Warriors, PHX= Suns ); } -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
Stuart White [EMAIL PROTECTED] wrote: : : sub ParseLineForHomeAndVisitors() : { : if ($_ : =~/(Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers| : Celtics|Pacers|Pistons|Wizards|Warriors|Bulls|Hawks| : Raptors|Magic|Heat|Kings|Rockets|Nuggets|Grizzlies| : Jazz|Knicks|Nets|Supersonics|'Trail Blazers'|Bucks| : Timberwolves|Hornets|Sixers|Bobcats)/) : { : @teams = /([[:alpha:]]+)/g; : } : return (@teams); : } When writing a subroutine, think of it as a miniature program. Something is passed in, processed, and output. Some subs only do one or two of those, but many do all three. Try not to process anything that is not local to the sub. In ParseLineForHomeAndVisitors(), $_ is not local to the sub, neither is @teams. It would be better to pass that value in: sub ParseLineForHomeAndVisitors { my $line = shift; my @teams = ( $line =~ /([[:alpha:]]+)/g ); return @teams; } I left out the validation because the sub isn't named ParseLineForHomeAndVisitorsIfLineIsValid() and because, IMO, that's too much work for one sub. For the validation I'll give a hint: Don't use a regex. Read three slides from M-J Dominus: http://perl.plover.com/yak/hw2/samples/slide007.html : I tried the same thing with my hash: : : CreateAbbrevAndNicknamesHash(); : : and here's the sub: : sub CreateAbbrevAndNicknamesHash() : { : my %AbbrevAndNicknames; : %AbbrevAndNicknames = ( :IND= Pacers, : . : . : . : ); : : : } The big question here is: Why a subroutine? If you want to create a hash, create a hash: my %AbbrevAndNicknames = ( IND = 'Pacers', NJN = 'Nets', DET = 'Pistons', NOH = 'Hornets', #check this MIL = 'Bucks', CLE = 'Cavaliers', BOS = 'Celtics', NYK = 'Knicks', MIA = 'Heat', PHI = 'Sixers', TOR = 'Raptors', ATL = 'Hawks', WAS = 'Wizards', ORL = 'Magic', CHI = 'Bulls', CHA = 'Bobcats', SAC = 'Kings', MIN = 'Timberwolves', SAN = 'Spurs', LAL = 'Lakers', DAL = 'Mavericks', MEM = 'Grizzlies', HOU = 'Rockets', DEN = 'Nuggets', UTA = 'Jazz', POR = 'Trail Blazers', SEA = 'Supersonics', LAC = 'Clippers', GSW = 'Warriors', PHX = 'Suns', ); I don't see the point of the subroutine. If you want to return a hash from a subroutine, use 'return'. Note that foo() actually returns a list (or is it an array?). We decide to stuff the result into a hash. #!/usr/bin/perl use strict; use warnings; use Data::Dumper 'Dumper'; my %foo_hash = foo(); print Dumper \%foo_hash; sub foo { return ( SEA = 'Supersonics', LAC = 'Clippers', GSW = 'Warriors', PHX = 'Suns', ); } HTH, Charles K. Clarkson -- Mobile Homes Specialist 254 968-8328 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
RE: returning hashes, and arrays
Stuart White [EMAIL PROTECTED] wrote: : : I figured the small snippets, how to : print an array, how to split a string etc., was : better as it was more focused, and would apply : to not just the one example. That's a great way to break the program down, but over the years I have found that many beginners are asking the wrong question. Supplying a good answer to the wrong question doesn't usually help much. With just a bit more information, I can tell whether the question is the right one and whether I should invest my time in it or not. For example, here's your parsing sub: sub ParseLineForHomeAndVisitors() { if ($_ =~/Spurs|Suns|Mavericks|Lakers|Clippers|Cavaliers|Celtics| Pacers|Pistons|Wizards|Warriors|Bulls|Hawks|Raptors|Magic| Heat|Kings|Rockets|Nuggets|Grizzlies|Jazz|Knicks|Nets| Supersonics|'Trail Blazers'|Bucks|Timberwolves|Hornets| Sixers|Bobcats)/) { @teams = /([[:alpha:]]+)/g; } return (@teams); } The 'if' statement is doing 3 suspicious things. One, it is capturing the match. Two, I suspect 'Trail Blazers' in single quotes will never be found. And it is not obvious what happens if there is no match. It looks like @teams is a global variable, but since that is a Bad Thing, I would hope you weren't using it. More importantly, (IMO) the sub probably shouldn't be doing the line validation. That should be done to determine if this sub should be called. I could write a nice long answer about this sub, but I'd probably be answering the wrong question. : Here's 25 lines of sample input: : -- : Spurs 94, Suns 82 : 4/29/2003 SBC Center, San Antonio, TX : Officials: #16 Ted Bernhardt , #33 Sean Corbin , #15 : Bennett Salvatore : 1st Period : (12:00) Jump Ball Robinson vs Williams : (11:41) [PHX] Marion Turnaround Jump: Missed [snip] : Thanks. Is each input example like this.? Is there a chance that a second line like Spurs 94, Suns 82 will show up? Or will it be in a different dataset (file, recordset, etc.)? The reason I ask Is that there is probably a better way to pick this line out of the file than that it contains team names. For example, it seems to be the only line that will match /[[:alpha:]]+\s+[[:digit:]]+,/. It also seems to be the first line. Is it always the first line? my $first_line = DATA; my @teams = $first_line =~ /([[:alpha:]]+)/g; As I progress with my own skills I find that programming is just manipulating of one form of data to another form. I haven't really learned more about perl in the last year, I've learned more about pattern recognition and how to apply it to the data coming in and leaving my scripts. I have also find that the better idea of what the output should be, the easier (and faster) I can create the solution. : The big picture is creating a box score. I have no idea what a box score is. I am sports deficient and only know this is basketball because of the categories you mention. : the categories are points, offensive rebounds, : defensive rebounds, assists, steals, turnovers, : field goals attempted, field goals made, blocks : and fouls. There are field goals in basketball?!? : Does that help? Yes. HTH, Charles K. Clarkson -- Mobile Homes Specialist 254 968-8328 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response