This week's book giveaway is in the Kotlin forum.
We're giving away four copies of Kotlin for Android App Development and have Peter Sommerhoff on-line!
See this thread for details.
Win a copy of Kotlin for Android App Development this week in the Kotlin forum!

Rob Bank

Ranch Hand
+ Follow
since Jan 11, 2018
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Rob Bank

Thank you,

I figured parse() needs a scanning order in line with my input.
I figured compareTo() needs to have finishTime first and challengeRating second for RaceResult to be able to calculate places and points correctly. Remaining fields' order should be irrelevant.
The order in Participant() I set in line with my input.
The order in hashCode() I set in line with my input. As I understand this creates references to instances but I'm not aware where those references are needed. As to what order it needs - my understanding is it doesn't matter.
The order in toString() I set in line with compareTo(). As I understand this is used to convert type of finishTime from long. As to what order it needs - my understanding is if it matters, finishTime needs to come first.
(scanDuration() operates on DURATION_PATTERN so I haven't paid attention as to ordering here - however; i set parse() to scan for duration lastly in line with my input.

And as a reminder just to be clear - Participant runs as intended on my input now - the input which I have modified to be challengeRating,firstName,lastName,teamName,finishTime.

Breakpoints - Roger (I'm using Eclipse).
11 months ago
So I regained the Participant class's ability to cope with my data. Modified the input data to A,Mick,Mickelsson,New,York,1.41.22 and also turned out DURATION_PATTERN had colons instead of dots as hour, minute and second separator as in my data.

No luck on RaceResult though as per below.

While the reason(s) to "test 1" not printing to terminal can be a bunch of stuff, my money are on that I'm back at my earlier query on the link between lineOfCsv and path. How does the RaceResult parsing communicate with Participant's parsing?
In other words: When the first RaceResult is being created (line 1 in pathResult is parsed), as I understand, it calls a Participant parse via lineOfCsv. How do I tell the RaceResult parsing to coordinate it's parsing with lineOfCsv?
11 months ago
Thanks S,

Are you sure that the file you're reading from is not empty, and that the output is directed to where you expect it to be?

Yes and yes.

Went over the dialogue again, I kind of missed this part:

This is how I would format the input data per participant:

My input data is this:
(where New,York, is mostly missing).
While I think I can come up with regexes to modify the input data to exclude 1., and ,+0.00.00, I cannot rearrange the different fields.

Now, if the CSV really were formatted like that, here's the code I would use to process it all:

Specifically in your latest Participant class from line 21 Participant(...) { to line 114 return new Participant() where there are a number of blocks with different orders on the Participant fields, does any of the blocks require the input data to be 1.41.22, A, Mickelsson, Mick, New York? I did not grasp the function of all of the blocks. I'm aware that the number of fields in some blocks must match the number of fields in the input data, but I'm not sure on all blocks as to where the order needs to be the same. I did also try the code without luck on a testfile with format:

Just came to think of testing the code on a testfile like below but my current Participant version is not optimized for it and my eyes are giving up for tonight
11 months ago
Lightbulb, I think I get the intension of path in RaceResult. It enables a main shortcut like;
11 months ago
Thanks Stephan,

this is how the main method would look:

Can I check if you are in C# mode? Seems var is not a Java syntax. And RaceResult parse does not accept path so do you mean;

This does not printf anything but neither do I get any direct errors so I'm thinking this could work once I figure out how to correctly implement some modifications I did to Participant to more accurately match my app objectives.
11 months ago
I understand most of your latest code package Stephan even though I'm unable to grasp some of the concepts after some 10 nights of studying and testing. For example TreeMap::new which pointed me into TCL something that I couldn't grasp (and please don't waste your time on explaining it, I'm just examplifying what I mean by concept).

Those concepts aside, I'm still stuck on the usage of lineOfCsv in the Participant class and path in the RaceResult class and how they relate.

As I see it, RaceResult invokes Participant participant. There is no invoking the other way around. So, after I in my main class do Participant.parse(lineOfCsv), RaceResult can operate on my data parsed into Participant. Hence, what is the intention of the RaceResult class reading path?

I guess me not getting the above relation makes using the the below difficult

What seems most logical to me (still not knowing what to do with RaceResult's path) would be to (in my main class) do

where I get errors like Cannot make a static reference to the non-static method participants() from the type RaceResult

Yeah, so, stuck. I'm thinking I maybe should be doing something with lines in RaceResult but...

I'm really sorry for my repeated questions on this but I take comfort in knowing you feel free to Ignore them!
11 months ago
If the contents under a URL have not previously been read and processed, this is how I read HTML and write .txt (yes, naming and other style issues leared in this thread have not yet been corrected);

11 months ago
To elaborate, I'm writing an application for a weekly occurring local endurance event. The aim is to create a total league, where points would be distributed and added in line with the latest results. Optimally, this application would be put on a webserver, checking every n:th minute whether new results are available. If not, shut down application. If yes but with errors, notify me then shut down application. If yes and no errors, do calculations, generate new points and total standing in table format (place firstName lastName point1 point2 ... pointTotal) and publish as HTML (write over last publish). I might add challengeRating, duration and difference to the table at some point so I don't want to exclude them from the Participant object yet. However, teamName won't be used. One possibly quite big challenge is the server migration, partly since all options are likely Linux-based (I've understood that the Java syntax varies between Windows and Linux distros), but that's a future concern. I have not yet thought deeper about how I would go about the adding points to table (and rearrange places according to updated pointTotal), though it would be fun to try to implement a database structure and manipulate the total standing table with SQL queries.

I have created functions for checking whether new results have been published and implemented corresponding shutdown or continue. Due to high likelyhood of misspells and name order switches (firstName lastName vs lastName firstName), I've created a correctNameDatabase (a .txt with firstName,lastName) against which new results are checked for misspells (Levenschtein Distance max 2), name order switches or combinations of the two. If new name, then it is added to correctNameDatabase. Below is some raw example HTML (to be transparent, ... indicates cut-off), names only modified. However, there are many variations in this formatting so it wouldn't be straightforward for you to try to implement something specific for this format. The HTML reading I've written has been testrun and modified to cope with all formatting variations in the past two years' results. For example, some people run in groups, where names might be separated by comma, and or /. They are to be excluded. The HTML tags can be upper- or lowercase. The parenthesis (Start: 35, Dnf: 4, Disq: 1) might not be there. There are variations e.g. in the word Disq. Mostly, there is no teamName or similar. And so on. Point being, discussing how the HTML is parsed would be a marathon. Stuff that could be discussed is, at least, whether or not to write placeNumber and difference to pathResults (which due to Stephan's insights on calculation vs reading, I will).

<H3><A NAME="A">  A</A></H3>

 (Start: 35, Dnf: 4, Disq: 1)

  1. John Johnsson                                            43.29
  2. Robert Robertsson                                        45.18     +1.49
  3. Mick Mickelsson                                          54.23    +10.54
  Dnf Jen Jensen                                              Dnf

<A href="#A">A</A>
<A href="#B">B</A>
<A href="#C">C</A>
<H3><A NAME="B">  B</A></H3>

 (Start: 49, Dnf: 0, Disq: 4)

  1. Ken Kenson                                              38.14
  2. Joe McCallan                                            45.20     +7.06
  3. Johnny Walker                                           55.24    +17.10
 Disq Matthew Chambers                                       Disq

But since you asked on the HTML parser, Carey, I use And to elaborate a bit - see my next post (character limit for the post reached).

I've been awfully busy so I have not yet tried your code Stephan but looking a bit closer at it, first, I found this little math trick a fantastic combination of clever and easy;

Second, being unfamiliar with the code used for getPlaceNumber, I'm not sure whether places after a shared placeNumber are skipped in line with the amount of participants sharing it, but I guess I will find out. I mean, if the first two have the same finishTime (i.e. both have placeNumber 1), then the following placeNumber should be 3.
Third, I see that you still throw new IllegalArgumentException if || teamName == null. I removed that part since teamName is mostly null. Am I missing something in my reasoning? That removal was one step in getting the Participant class to cope with my data.

11 months ago
Let me rephraze the clumsily written second last sentence.
So, as I see it, I can either try to implement some .replaceAll when I'm modifying the total HTML string I have read, to exclude the teamNames (which if can be done, I have no clue how to), or utilize the DURATION_PATTERN for which space / comma is indifferent, apart from that the pattern would have to look slightly different.
1 year ago
Ahaa, I assumed you had a typo in previous post with the plus not being preceeded by a space. It is not a plus sign, the plus is just the regex one or more;

At URL read and corresponding txt file write, .replaceAll(" +", ",") gives ...,New,York,...

HTTP POST and AJAX what? In a rush so in layman terms, I read a web-page and get the text that includes all HTML-tags. I filter out the text I want as CSV using a set of .replaceAll(). Sorry for the confusion, I did not put much effort to the phrasing as by "reading a web adress" I assumed it was clear that I'm reading the contents "under it". I still don't have access to my code so I can't comment on the technical way in which the data is read.

Why so? My earlier comment was based on the assumption that you were talking about the + sign in regex terms. I.e. that you were querying on my choise of separating each object (not sure I'm using the right word here, but with each object I mean each firstName, each lastName, each duration and so on..) with comma instead of space. Sure, it sounds more straightforward to extract teamNames by implementing other separation of their words than the other data's comma if I were to use it, but I'm looking to dump it alltogether. So, as I see it, I can either try to implement some .replaceAll at initial file generation to exclude the teamNames being read (which if can be done, I have no clue how to), or utilize the DURATION_PATTERN for which space / comma is indifferent, apart from that the pattern would have to look slightly different.

Thanks, I get your point in principle on redundancy.
1 year ago
Thanks a million guys. Been offline a while and will be looking closer at this starting tomorrow. Studying it & relating theory should take a few days.

Meanwhile just a quick response on the questions.
matcherPoint.reset(line) sets the matching region of line to start,end (matcherPoint is initiated to "" i.e. matcher.region(0,0))

Yes, ONE thing / property. The choise of commas; can't recall any particular reason for it at start of project, other than that's the data separation formatting on file orders and generations at work and that it would be the best format considering a possible future database setup. I’m basically reading the source code of a URL. As far as I understand from a googling, that is the HTML request body, no? Don’t have access to my code currently so can’t say how it’s done technically.

The initial thought of calculating point went way over my head so I settled for listing them – great. Calculating place also fixes an issue I’ve been having with incorrect place after removing some performances due to certain criteria – great. Since you didn’t know about that, I’m curious as to why you prefer calculating place and difference instead of reading them. I guess I will find that out while looking closer at your code though.

Robert and Mick sharing place but having different point was an example of what I was trying to fix with my arrow anti-pattern loop. And while it fixed just that, the issues I had were;

... (i) not if there are more than two participants sharing a place and (ii) not if there is additionally, say, in course B, a shared place.

1 year ago
Thanks for the pointers! I learned a great deal.
  • Ok
  • Ok (nice to learn that try blocks take care of the closing by default!)
  • mPoint is short for matcherPoint. I see a lot of Pattern p = … and Matcher m = …  so this seemed like a suitable naming - switching.
  • Ok
  • I’ll think about what would be logical to split into classes/methods and with that as base maybe try some GuardClause conversions of remaining superfluous nesting.
  • Ok. If I understand correctly, e.g. lines 25-33 should be put outside the if-bracket. I guess this is readability related / common praxis more than computationally significant?

  • Since why something happened seems like a question longing for a technical answer, I’m not sure what info you are after. But cities is neither really really cities - it can be a club or a city or whatever the results uploader decides to put there. I have seen up to three words used on occasion; however mostly it is null. Let’s call it a property of the participant that in theory can be anything between zero and n strings. Heck, come to think of it, there might even be integers there There will not be a + sign though. Yes?

    Course & letter is the official naming, where the letter stands for level of challenge in alphabetically ascending order. If you’re feeling invincible, run the toughest Course A.

    Point calculation:
    A: 100, 95 and 90 for top-3, then -2points per place, down to a minimum of 1point/participant
    B = 0.88*A rounded to even numbers, down to a minimum of 1point/participant
    C= 0.77*A rounded to even numbers, down to a minimum of 1point/participant

    Why are two… Oops, because of my manual summary mistake. This is what it would look like on file;
    A,2.,A2,Mick,Mickelsson,New,York, 1.41.22,+10.00,92
    1 year ago
    This got really ugly, long, and buggy - I believe I'm just scratching the surcafe of what the Participant object could provide in terms of flexibility.

    So I've previously written points to new lines based on course, producing the unwanted feature of different points in case shared place;

    Now I look to iterate through the list to find these Mick Mickelsson's and raise their points. To simplify, I added a coursePlace Participant object. The below stuff copes well with the above three-lined file, but (i) not if there are more than two participants sharing a place and (ii) not if there is additionally, say, in course B, a shared place.

    Any thoughts on how to do this bugfree and more elegantly, or just bugfree?

    1 year ago
    Hmm, yeah that's not going to work for id's >9 but that should be easy to fix.
    1 year ago