• Maurits (cs)

    s/Do While Not/Do Until/

  • fcarlier (cs) in reply to Maurits

    Maurits:
    s/Do While Not/Do Until/

    Not really... Do While Not is perfectly legal Visual Basic, IIRC

  • (unregistered) in reply to fcarlier

    You miss the point.  "Do Until" is easier to read and easier to understand.

  • Manni (cs) in reply to fcarlier

    Although it is legal, I prefer to use "Do Until" in these kinds of cases to prevent confusion. That way if someone has to scan through my code quickly to find a problem, they don't have to waste time figuring out what my "Do" loop is evaluating by negating the status of the condition.

    As for this particular coder, clearly he should have split this up into 4 columns:
    Hours_tensColumn as Integer
    Hours_onesColumn as Integer
    Minutes_tensColumn as Integer
    Minutes_onesColumn as Integer

    Now *that* is what I call efficient. Small data types, no need for string splitting functions...c'mon this is the best!

  • Manni (cs) in reply to Manni

    Heh I just noticed that while he's in the loop, he keeps reassigning the value of TotalHours, not adding to it. Therefore TotalHours will reflect only the total hours of the last record he pulls. The alternative is that TotalHours is a standardized number like 40 (for work hours in a normal week), and he's only expecting it to be that standardized value at the end. In that case, there's no reason to read that value for every record. Not to mention that his code will completely bomb if the ":" character is missing or not in the right place thanks to someone hand-jamming the database. Long live "On Error Resume Next"!

  • Manni (cs) in reply to Manni

    Manni:
    Heh I just noticed that while he's in the loop, he keeps reassigning the value of TotalHours, not adding to it...

    *sigh* It's supposed to do that. Ignore that part, or bring on the flames.

  • fcarlier (cs) in reply to

    :
    You miss the point.  "Do Until" is easier to read and easier to understand.

    Okay, I see. Well, I saw the 'Do Unitel Not rs.EOF' pattern so often by now, that I got used to it :).

    About storing the time... Here's how I would do it: just store the it as minutes. You just do a SELECT SUM(Minutes) and then convert it into a nice HH:MM format (just dividing by 60 and getting the remainder). Aah, life can be easy :).

    Alternatively, you could store it as a DateTime or so, but I guess that would be some overhead (although you can use SQL's built in functions, then)

  • Guayo (cs)

    He surely did know in advance that calculating the total time of those time sheets wouldn't be a task for the faint of heart.
    His tools?
    * A permissive language that allows a lot of implicit type conversions.
    * A "powerful" Replace function to cast any unwanted char to oblivion.
    * Self confidence... You need a lot of self confidence to code this. Or maybe if not confidence then a lot of balls.

    I don't fully understand the reasoning behind this piece of code. There are lines that seems eccentric, weird, absurd. Someone could say they are stupid.
    Myself... What can I say? I'm not so sure of my programming skills after looking at this. How can I dare to judge the code when clearly I don't have the needed clues to understand it?
    Although something seems obvious (I have to say), when he put that isolation level in the recordset, he wasn't overstating what he would do with it.

  • (unregistered)

    I guess one of the side-WTF's here is this:

    If <font color="#0000ff">Len</font>(mTotatTime) = 1 Then
    mTotatTime = mTotatTime & "0"
    End If

    So when the total time is less than 10 minutes, it should multiply it by 10? WTF?

  • (unregistered)

    The problem here is SQL weakness. All that code could & should've been done in a simple SQL math aggregation. The Do While is not a problem.

  • skicow (cs) in reply to
    :
    I guess one of the side-WTF's here is this:
    If <FONT color=#0000ff>Len</FONT>(mTotatTime) = 1 Then
    mTotatTime = mTotatTime & "0"
    End If

    So when the total time is less than 10 minutes, it should multiply it by 10? WTF?

    The '&' symbol is the concatenate function in VBScript. If the minutes variable is only one character then he's concatenating a zero on the end of it. So if it's 2 it'll now be 20...not that my understand of the code leads me to understanding WhyTF he is doing this...Meh.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    <FONT size=3><FONT face="Times New Roman"> <o:p></o:p></FONT></FONT>

     

  • Mike R (cs) in reply to
    :

    The problem here is SQL weakness. All that code could & should've been done in a simple SQL math aggregation. The Do While is not a problem.



    Maybe... Depends on where you want the load to be, on the SQL server, which is servicing (potentially) hundreds of users, or on the local machine, which is serving one user...

    But, the cost of a simple aggregation may be negligible enough to just use the SQL Server's engine in this case.

    (Clicking "Post" in hopes that my message actually get posted this time[*-)])
  • (unregistered) in reply to skicow
    skicow:
    [image]  wrote:
    I guess one of the side-WTF's here is this:
    If <FONT color=#0000ff>Len</FONT>(mTotatTime) = 1 Then
    mTotatTime = mTotatTime & "0"
    End If

    So when the total time is less than 10 minutes, it should multiply it by 10? WTF?

    The '&' symbol is the concatenate function in VBScript. If the minutes variable is only one character then he's concatenating a zero on the end of it. So if it's 2 it'll now be 20...not that my understand of the code leads me to understanding WhyTF he is doing this...Meh.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    <FONT size=3><FONT face="Times New Roman"> <o:p></o:p></FONT></FONT>

     

  • fcarlier (cs) in reply to Mike R

    Mike R:


    Maybe... Depends on where you want the load to be, on the SQL server, which is servicing (potentially) hundreds of users, or on the local machine, which is serving one user...

    But, the cost of a simple aggregation may be negligible enough to just use the SQL Server's engine in this case.

    Well... I assume doing this kind of math on the server side is a lot faster than opening a recordset on the client and reading the rows one by one!

  • fcarlier (cs) in reply to fcarlier

    ... and thus puts less stress on the server in the end, of course!

  • (unregistered) in reply to skicow

    I think what the coder really wanted to do was concatenate the "0" at the beginning of times with single digits, i.e. 2 was supposed to become 02. Which he of course stuffed up.

    Anyone else notice how "Totat" is spelt wrong?

  • (unregistered)

    Does this add up the minutes correctly? It seems from Replace(dbQTS("TotalHours"), ".", ":") that he's must be using metric time to get the minutes right. A value of "1.20" hours would be translated to "1:20" instead of the correct "1:12" (assuming the TotalHours field is a simple float value).

    I also love the clever use of Replace() and Left() to round the extra minutes to hours (though it only works for values of 99 minutes or less).

    Wouldn't have just a SUM(TotalHours) worked?

  • (unregistered) in reply to skicow

    2 -> 20

    1 -> 10

    3 -> 30

    See the pattern? Adding a zero to the end of a whole number is the same as multiplying by ten.

  • Blue (cs) in reply to fcarlier
    fcarlier:

    [image]  wrote:
    You miss the point.  "Do Until" is easier to read and easier to understand.

    Okay, I see. Well, I saw the 'Do Unitel Not rs.EOF' pattern so often by now, that I got used to it :).

    About storing the time... Here's how I would do it: just store the it as minutes. You just do a SELECT SUM(Minutes) and then convert it into a nice HH:MM format (just dividing by 60 and getting the remainder). Aah, life can be easy :).

    Alternatively, you could store it as a DateTime or so, but I guess that would be some overhead (although you can use SQL's built in functions, then)

  • Bustaz Kool (cs)

    Ultimately, the problem is that they are storing numeric data (Number of Hours and Number of Minutes) as a string.  Compound this with the fact that they are then storing these two values in the same field.  Small wonder that everything runs to the gutter from there.  I will grant that this particular implementation runs there quicker than others.

    select SUM(Hours * 60 + Minutes) TotalMinutes 

      from MyTable

    OR, if you prefer

    select SUM(Hours * 60 + Minutes) / 60 TotalHours,

      Sum(Minutes) % 60 TotalMinutes 

      from MyTable

    Let the application perform the proper formatting of the number(s) from there.

     

  • skicow (cs) in reply to
    :

    2 -> 20

    1 -> 10

    3 -> 30

    See the pattern? Adding a zero to the end of a whole number is the same as multiplying by ten.

    AH! I see now, yes it's the same as multiplying by ten...but that's not what the code was actually doing.

  • brill (cs) in reply to
    :
    You miss the point.  "Do Until" is easier to read and easier to understand.


    You do realize that "Do Until" would be it's own WTF here don't you?

    The problem comes to when the loop test is evaluated:
    <font color="#0000ff"> Do Until</font> will evaluate after the code has executed
    <font color="#0000ff"> Do While [Not]</font> evaluates before the code executes, which this fellow actually does want to do.

    In other words, he doesn't want to evaluate the loop if <font color="#800080">dbQTS.EOF</font> is <font color="#a52a2a">true</font> (don't bother if we're at the end of the file/table/etc).

    Both forms are valid and useful depending on what your trying to do and it's not limited to VB... e.g. in Java it would be:


    <font color="#0000ff"> while</font>(!<font color="#800080">dbQTS.EOF</font>){
        <font color="#006400">// do something</font>
    }

    <font color="#0000ff"> do</font> {
        <font color="#006400">// do something</font>
    } <font color="#0000ff">while</font>(!<font color="#800080">dbQTS.EOF</font>);

    this first form would be correct, the second would be a WTF in this case.

    Now... why is it that every time I read this blog, I see more WTF's in the comments than in the actual posted code... a bit of a generalization I admit, but I see that many people around here should be reading and learning than posting just to hear the keyboard click!


  • (unregistered)

    This code could use a few constants to make it more readable and perform better.  For example:

    Const Zero = 0
    Const One = 1
    Const Two = 2
    Const Sixty = 60
    Const ADODBdotRecordset = "ADODB.Recordset"
    Const DB = "db"

    Other than that I think it is pretty good code.  Alot easier to read than if it was done in T-SQL.

  • (unregistered) in reply to
    :

    You can't quote me! Nyah-Nyah!

    Stupid quote function!

  • (unregistered)
    :

    This code could use a few constants to make it more readable and perform better.  For example:

    Const Zero = 0
    Const One = 1
    Const Two = 2
    Const Sixty = 60
    Const ADODBdotRecordset = "ADODB.Recordset"
    Const DB = "db"

    Other than that I think it is pretty good code.  Alot easier to read than if it was done in T-SQL.

     

    OMG!  You are a walking WTF!  might as well add this too..

    Const MattDamon = "MattDamon"
    Const Hour = "hh"
    Const Minutes = "mm"
    Const TrueValue = "True"
    Const FalseValue = "False"
    Const NegativeOne = "-1"

    Where did you learn to code?  I know.  You got it from Lean how to code VB in 24 hours huh?

  • Bellinghman (cs) in reply to brill
    brill:
    :
    You miss the point.  "Do Until" is easier to read and easier to understand.


    You do realize that "Do Until" would be it's own WTF here don't you?

    The problem comes to when the loop test is evaluated:
    <font color="#0000ff"> Do Until</font> will evaluate after the code has executed
    <font color="#0000ff"> Do While [Not]</font> evaluates before the code executes, which this fellow actually does want to do.

    In other words, he doesn't want to evaluate the loop if <font color="#800080">dbQTS.EOF</font> is <font color="#a52a2a">true</font> (don't bother if we're at the end of the file/table/etc).

    Both forms are valid and useful depending on what your trying to do and it's not limited to VB... e.g. in Java it would be:


    <font color="#0000ff"> while</font>(!<font color="#800080">dbQTS.EOF</font>){
        <font color="#006400">// do something</font>
    }

    <font color="#0000ff"> do</font> {
        <font color="#006400">// do something</font>
    } <font color="#0000ff">while</font>(!<font color="#800080">dbQTS.EOF</font>);

    this first form would be correct, the second would be a WTF in this case.

    It's a pretty WTF language if

    do until x {

    }

    doesn't evaluate the condition until after the first loop.

    brill:

    Now... why is it that every time I read this blog, I see more WTF's in the comments than in the actual posted code... a bit of a generalization I admit, but I see that many people around here should be reading and learning than posting just to hear the keyboard click!


    I don't know. Perhaps you need to look a little more closely.

  • Bellinghman (cs) in reply to Bellinghman

    Oh, and just how does one persuade this PoC web software to actually do the right thing? Its quoting is completely anti-intuitive.

  • Manni (cs) in reply to brill
    brill:
    [image]  wrote:
    You miss the point.  "Do Until" is easier to read and easier to understand.



    You do realize that "Do Until" would be it's own WTF here don't you?

    The problem comes to when the loop test is evaluated:
    <FONT color=#0000ff>Do Until</FONT> will evaluate after the code has executed
    <FONT color=#0000ff>Do While [Not]</FONT> evaluates before the code executes, which this fellow actually does want to do.

    In other words, he doesn't want to evaluate the loop if <FONT color=#800080>dbQTS.EOF</FONT> is <FONT color=#a52a2a>true</FONT> (don't bother if we're at the end of the file/table/etc).

    Both forms are valid and useful depending on what your trying to do and it's not limited to VB... e.g. in Java it would be:


    <FONT color=#0000ff>while</FONT>(!<FONT color=#800080>dbQTS.EOF</FONT>){
        <FONT color=#006400>// do something</FONT>
    }

    <FONT color=#0000ff>do</FONT> {
        <FONT color=#006400>// do something</FONT>
    } <FONT color=#0000ff>while</FONT>(!<FONT color=#800080>dbQTS.EOF</FONT>);

    this first form would be correct, the second would be a WTF in this case.

    Now... why is it that every time I read this blog, I see more WTF's in the comments than in the actual posted code... a bit of a generalization I admit, but I see that many people around here should be reading and learning than posting just to hear the keyboard click!


    You do realize that you don't understand VB Do loops, right? If you put the conditional statement at the top of the Do loop, as in

    Do Until dbQTS.EOF

    ...then the evaluation criteria will be examined before the loop is entered. The loop breaks when that statement evaluates to True. If no records are returned, then .EOF = True, and the loop is skipped. What you're thinking of is if he did this:

    Do

    ...

    While dbQTS.EOF = False

    (forgive me if the syntax is wrong, I never use this method)

  • Stan Rogers (cs) in reply to Manni

    Do comes in four basic flavours:

    Do While <condition>
    'Code never guaranteed to execute
    Loop

    Do Until <condition>
    'Code never guaranteed to execute
    Loop

    Do
    'Code guaranteed to execute at least once
    Loop While <condition>

    Do

    'Code guaranteed to execute at least once

    Loop Until <condition>

    The While/Until question is a matter of whether the condition will be true or false while the loop executes, and is more-or-less a matter of convenience and readability. "Do While Not Thing Is Nothing" sounds bad and is less maintainable than "Do Until Thing Is Nothing". Multiple negatives are just not asking for no trouble.

  • Bellinghman (cs) in reply to
    :
    :

    You can't quote me! Nyah-Nyah!

    Stupid quote function!

    And does this?

  • (unregistered)

    I think most everybody missed the fact that the time is stored in the database as hours - in decimal! He (or she) could just add the time!

    Instead, he first replace stringifies the number and replaces "." with ":". The next two replaces separate the hours and minutes (using Left and Right) and removes the colon (that he just added!) from TotalHours and keeps a running total.

    After some funky string arithmetic (good thing vb does all the string->number conversions for him), he ends up with hours and minutes. Sometimes he even ends up with hours and minutes * 10.

    wtf?

  • (unregistered)

    As the poster of this great piece of code, let me add one more piece of comedy: we got a CV through the other day from the guy who originally wrote this, wanting to do more work for us [:|]

  • cjs (cs) in reply to
    :

    The problem here is SQL weakness. All that code could & should've been done in a simple SQL math aggregation. The Do While is not a problem.



    You just need to switch to PostgreSQL. Try this on for size:
    <font face="Courier New">
    CREATE TEMPORARY TABLE timesheet_entry (

        timesheet_entry_id  int NOT NULL PRIMARY KEY,

        timesheet_id        int NOT NULL,

        time_spent          interval NOT NULL

    ); 


    INSERT INTO timesheet_entry VALUES (1, 1, '1 hour');

    INSERT INTO timesheet_entry VALUES (2, 1, '10 minutes');

    INSERT INTO timesheet_entry VALUES (3, 2, '97 minutes');

    INSERT INTO timesheet_entry VALUES (4, 2, '2.5 hours');

    INSERT INTO timesheet_entry VALUES (5, 2, '4 hours 12 minutes');

    INSERT INTO timesheet_entry VALUES (6, 2, '0.5 hour');

    INSERT INTO timesheet_entry VALUES (7, 2, '10 minutes');

    INSERT INTO timesheet_entry VALUES (8, 2, '0.5 day');

    INSERT INTO timesheet_entry VALUES (9, 2, '3:29');


    SELECT * FROM timesheet_entry;


     timesheet_entry_id | timesheet_id | time_spent

    --------------------+--------------+------------

                      1 |            1 | 01:00:00

                      2 |            1 | 00:10:00

                      3 |            2 | 01:37:00

                      4 |            2 | 02:30:00

                      5 |            2 | 04:12:00

                      6 |            2 | 00:30:00

                      7 |            2 | 00:10:00

                      8 |            2 | 12:00:00

                      9 |            2 | 03:29:00

    (9 rows)


    SELECT sum(time_spent) FROM timesheet_entry WHERE timesheet_id = 2;


    </font> <font face="Courier New">      sum      

    ----------------

     1 day 00:28:00

    (1 row)</font>

  • Goudinov (cs) in reply to

    :
    As the poster of this great piece of code, let me add one more piece of comedy: we got a CV through the other day from the guy who originally wrote this, wanting to do more work for us Indifferent

    LOL!  I didn't have anything worthwhile to add... I just wanted to hear my keyboard click.

    clakity clikity clakity clock!

    [:P]

  • (unregistered)

    My additional big WTF:

    Using adOpenDynamic and adLockPessimistic instead of (in this particular case) the correct and more efficient adOpenForwardOnly and adLockReadOnly.

  • Katja (cs)

    Do While <condition1>

    'Code never guaranteed to execute

    Loop While <condition2>


    Do Until <condition1>

    'Code never guaranteed to execute

    Loop While <condition2>


    Do While <condition1>

    'Code never guaranteed to execute

    Loop Until <condition2>


    Do Until <condition1>

    'Code never guaranteed to execute

    Loop Until <condition2>


    Now, wouldn't these two be fun additions? [8-|] I wonder if these are legal constructions or not. :-) And what will happen if they are legan and you're using them....
  • (unregistered)

    I've since left the company where I found a bit of creative coding.

     I was over hauling a timesheet system (vb front-end, access back) for a client, ddep in the code there was a timer that every  3 minutes checked to see if the application had been idle for more than 5 minutes (yes 3's into 5 now go!). Not too bad well it gets worse. The system would record the current date-time every time a mouse event happen in (wait for it) the registry file! every time you moved the mouse it would convert the full date time to a string and then write it to the registry (each day it would make a new key name with the current date to store this)! whats more the routine to check the current date-time with one in the registry went a bit like this

    <Psuedocode>

    date1=cstr(registrydate())

    date1=right(date1,5) 'time in hours/minutes

    date2=cstr(now())

    date2=substring(date2,5)

    if(cint(left(date2,2))=cint(left(date1,2)))

       if(cint(right(date2,2))=cint(right(date1,2)))

          lockscreen();

       end if

    end if

    </Psuedocode>

    compairing 2 date types stored in memory would be too complex, much safer to store it in the registry and perform 2 substrings and 2 datatype conversions.

  • Sweets (cs)

    maybe I'm crazy, but I would think that rsQTS would be the correct hungarian notation not dbQTS...
    QTS=  Q??? Time Sheet ??????

  • Jacob K (cs)
    I guess one of the side-WTF's here is this:
    If <font color="#0000ff">Len</font>(mTotatTime) = 1 Then
    mTotatTime = mTotatTime & "0"
    End If

    So when the total time is less than 10 minutes, it should multiply it by 10? WTF?



    Skicow: He understood that that is the concat operator. By adding a zero on the end of any number, you are essentially multiplying it by 10. He should have it like so:

    mTotatTime = "0" & mTotatTime [sic]

  • Katja (cs) in reply to Sweets

    No, dbQTS is correct. The Q stands for Query. Thus you get: Database System Query Time Sheet.

    Very logical, don't you agree?

  • (unregistered) in reply to
    :

    This code could use a few constants to make it more readable and perform better.  For example:

    Const Zero = 0
    Const One = 1
    Const Two = 2
    Const Sixty = 60
    Const ADODBdotRecordset = "ADODB.Recordset"
    Const DB = "db"

    Other than that I think it is pretty good code.  Alot easier to read than if it was done in T-SQL.



    I couldn't agree more.  But I don't think you've fully clarified your const names.  I prefer:
    Const Minutes_NumberValue_One = 1

    And of course the stings:
    Const Minutes_String_ZeroToAppend = "0"
  • (unregistered) in reply to Jacob K
    Jacob K:
    I guess one of the side-WTF's here is this:
    If <FONT color=#0000ff>Len</FONT>(mTotatTime) = 1 Then
    mTotatTime = mTotatTime & "0"
    End If
    So when the total time is less than 10 minutes, it should multiply it by 10? WTF?



    Skicow: He understood that that is the concat operator. By adding a zero on the end of any number, you are essentially multiplying it by 10. He should have it like so:

    mTotatTime = "0" & mTotatTime [sic]

    Yeah, I realized what he was saying after I posted...

  • skicow (cs)

    ^^ D'oh! That was me not logged on! ^^

  • Blue (cs) in reply to skicow

    Ok, I officially give up on using the horribly broken quoting function.  It used to be that sometimes quoting wouldn't work, but at least the preview SHOWED that the quote didn't work.  Now I have some that I KNOW I checked, and the stuff I typed after the quoting is GONE.

    Will just have to go back to good old cut-and-paste and stop whining about quoting, I guess.  Whaddya want for free?

    -blue

  • (unregistered) in reply to Katja
    Katja:
    Do While <condition1>

    'Code never guaranteed to execute

    Loop While <condition2>


    Do Until <condition1>

    'Code never guaranteed to execute

    Loop While <condition2>


    Do While <condition1>

    'Code never guaranteed to execute

    Loop Until <condition2>


    Do Until <condition1>

    'Code never guaranteed to execute

    Loop Until <condition2>


    Now, wouldn't these two be fun additions? [8-|] I wonder if these are legal constructions or not. :-) And what will happen if they are legan and you're using them....
  • (unregistered) in reply to brill
    brill:
    [image]  wrote:
    You miss the point.  "Do Until" is easier to read and easier to understand.



    You do realize that "Do Until" would be it's own WTF here don't you?

    You do have any idea what you're talking about here don't you ?

     

  • drew (cs) in reply to Katja

    Katja:
    No, dbQTS is correct. The Q stands for Query. Thus you get: Database System Query Time Sheet.

    Very logical, don't you agree?

    sorry to disagree, but the 'rs' is more informative, and the db is just not correct in this instance. The variable is a recordset. You do not need to reference how your set of data is managed at the back-end from within a variable name, that would be tedious. drew..

  • cjs (cs) in reply to
    :
    [image] brill wrote:
    [image]  wrote:
    You miss the point.  "Do Until" is easier to read and easier to understand.



    You do realize that "Do Until" would be it's own WTF here don't you?

    You do have any idea what you're talking about here don't you ?

     

  • Katja (cs)

    I love the way this forum kills all posts with quotes from users who use FireFox. [:P] I bet there are quite a few FireFox users here... Also makes me wonder what they were about to say.

  • Ben Hutchings (cs) in reply to Katja

    The editing widget loses changes to comments that quote other comments with quotes in, in Firefox. Quoting comments without quotes in them seems to work.

Leave a comment on “Superfun Time Arithmetic!”

Log In or post as a guest

Replying to comment #:

« Return to Article