confusing loops (php)

Discussion in 'OT Technology' started by babygodzilla, Aug 11, 2003.

  1. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    so i have this 3-dimensional array for a scheduling program that looks like this
    $rows[$x][$y][$z]

    $x represents search results having the same 'code' (code is a column in the DB)
    $y represents the different 'courseNum' within one 'code'
    $z represents all the classes within one 'courseNum'

    since this is a course scheduling proggie, i have to check everything within one result against everything else in all the other results to look for time clonflicts. thats the part im confused at, how to loop thru all that.

    a lil visuals, it looks kinda like this:
    (please disregard underscores as spaces)
    ---------$x = 0------------
    ABC____123____Monday ($rows[0][0][0])
    ABC____123____Tuesday ($rows[0][0][1])
    ABC____474____Friday ($rows[0][1][0])

    ---------$x = 1---------------
    DEF____873____Thursday ($rows[1][0][0])
    DEF____090____Monday ($rows[1][1][0])
    DEF____090____Tues ($rows[1][1][1])

    ---------$x = 2----------------
    YUT____134____Mon ($rows[2][0][0])
    YUT____134____Fri ($rows[2][0][1])
    YUT____712____Tues ($rows[2][1][0])

    ABC is $x, within that,
    ABC 123 is $y, and within that,
    ABC 123 Monday is $z

    something like that. i hope its not too confusing....

    users can get up to 6 results (that means $rows can have a size of up to 6, or $x can be up to 6). i'll use 3 here.

    so now what the proggie should do is take one class from each result, and compare it to each other. if there are no time conflicts, then it'll be displayed in a table. it should go like this:

    comparing ABC 123 - DEF 873 - YUT 134

    $rows[0][0][0] - $rows[1][0][0] - $rows[2][0][0]
    $rows[0][0][0] - $rows[1][0][0] - $rows[2][0][1]
    $rows[0][0][1] - $rows[1][0][0] - $rows[2][0][0]
    $rows[0][0][1] - $rows[1][0][0] - $rows[2][0][1]

    after that it should compare ABC 123 - DEF 873 - YUT 712

    $rows[0][0][0] - $rows[1][0][0] - $rows[2][1][0]
    ...and so on

    so thats the process of one comparison. $x can be up to 6, $y can be something between 1 and 50 (or so...), $z can be something between 1 to 4.

    the more problematic issue here is the order of the loops, and the fact that we wont know how many search results ($x) there will be until users hit the submit button. i think im supposed to increment thru $z first, $x second, and $y last, or something like that... help? im confused, things are floating in my head and i think it make sense but not really...

    THANKS EVERYBODY!
     
  2. Astro

    Astro Code Monkey

    Joined:
    Mar 18, 2000
    Messages:
    2,047
    Likes Received:
    0
    Location:
    Cleveland Ohio
    Yikes!

    Around about this time I usually start thinking implementing a class data structure is a good idea...

    Well, you picked that data structure for a reason. You'll have to implement multiple for() loops to go through all the data. How you want to go about it doesn't matter too much since you have to loop through everything anyways. As long as your record sets are not too large, performance should be ok. But if you have a ton of data, then you may want to rethink your entire approach...
     
  3. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    hmm im not quite sure how to make a class out of it because all im doing is taking data out of the database and putting em all in that array. all my data is in a database.

    im confused about the loops, i cant get it to work correctly. it's like i have to increment $z first and then $x second and then $y last but somewhere in that process between $x and $y i have to increment $z...or something like that... :rant2: :eek3:

    ive actually forgotten much of my C++ experience :p i didnt even think about making a class. i just thought that i have everything in the DB and would simply use an array. how would you suggest using a class for this? and what of the loops?



    btw, performance wise there's no problem. the prog generated something like 20 tables in a couple of seconds, although they aren't correct :p
     
  4. Astro

    Astro Code Monkey

    Joined:
    Mar 18, 2000
    Messages:
    2,047
    Likes Received:
    0
    Location:
    Cleveland Ohio
    I'm not going to worry about performance... I'll let you handle that part.

    As for searching records, why not use the database? You can do some sweet stuff just from SQL and probably bypass the need for classes.
     
  5. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    yeah i do the SQL queries of course. so there's a search engine for classes. users type in the 'code' and 'courseNum' and code searches for em in the database. i put them in array only for the purpose of giving em specific positions to compare everything to everything. is there a way to do this comparison with SQL queries?
     
  6. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    do your courses have real date/time info in the database? like a startTime endTime??

    if so, i would settle all the scheduling conflicts and searching on the database side. I'm quite sure it can be done better that way, and with better performance.
     
  7. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    yes they do. how do i do it with SQL?

    one thing to note tho: there are calculations involved when checking for time conflicts. rite now the classes in the DB uses AM/PM system for the times. the way i do it now, i convert the times temporarily to 24-hour time for easy comparison. is it wiser to change the time to 24 hour when inserting into the database?
     
  8. Astro

    Astro Code Monkey

    Joined:
    Mar 18, 2000
    Messages:
    2,047
    Likes Received:
    0
    Location:
    Cleveland Ohio
    Which database engine you using? What field data type are you using to store the date/time?

    Just about ANY time you store a date and/or time format, you will want to pick a field type of time, datetime, or date. A text or varchar field for the date/time is ok if you're 100% sure you have NO plans to do any comparisons. By using an authentic datetime field, you can store the time in a uniform manner which will make it easier to perform calculations on later. MySQL's datetime field is formatted as: YYYY-MM-DD HH:MM:SS where HH = hours in 24hr format. With datetime (and a few other date related fields), you can then use functions like DATEFORMAT(), NOW(), MONTH(), DAY(), YEAR(), HOUR(), MINUTE(), and more (those may not be 100% correct - they're there for example).

    MySQL's DATEFORMAT() rocks - you can take whatever date/time you have and format it any way you wish from within SQL - which means no code updating if you decide you need the date reformatted. This means you can take the 24hr formatted time and convert it (and very easily) to 12hr format.

    It would probably be an ugly SQL SELECT statement, but you should be able to do your date/time comparisons with the WHERE clause and the BETWEEN statement (for example and just one of the several ways of doing this).
     
  9. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    i see. im using mySQL btw. all data is parsed from a text file the original text file has times formatted like

    1200 - 0210P
    1000 - 1100A

    there's no date by the way. just time.

    P being PM, A being AM. i have a separate column 'day' for that P and A.
    im not that familiar with mySQL so i stupidly just use varchar for timeStart and timeEnd. is that unwise?

    actually the problem right now isn't HOW i compare the classes. the way i do it now isn't that complicated, albeit a little long. although doing it with SQL is probably more efficient, i doubt users will notice the milliseconds of difference in processing time since the data displayed really isn't that big (still, I am VERY interested in learning how to do that with SQL). the only confusing part is the looping and comparing everything to everything. my head is exploding :sadwavey:
     
  10. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    well, if not for performance, it's a good idea for code read-ability and code re-use. Not to mention that it will take you much less time to make modifications to your code, and also it would take a lot less time to code it in the first place.

    But yeah, to reiterate what Astro said, it's always a good idea to store your dates as database-typed date fields rather than varchars. If not now, i'm sure in the future you would want to do comparisions, ordering, etc.
     
  11. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    of course, i agree with that code readability. ima learn that BETWEEN command. is there anything else to use for comparison.

    well i think that whether i use SQL queries to compare or just pure PHP, there will be loops involved. can you guys help me figure out the loop? so say using the example i displayed above, the loop should look like this i think : (im just gonna print up to $y, and for time's sake im not gonna print $rows everytime, just the subarrays)

    so comparing 2 classes at a time:

    [$courses1][$classes1] - [$courses2][$classes2]

    [0][0] - [1][0]
    [0][0] - [2][0]
    [1][0] - [2][0]

    [0][0] - [1][0]
    [0][0] - [2][1]
    [1][0] - [2][1]

    [0][0] - [1][1]
    [0][0] - [2][0]
    [1][1] - [2][0]

    ... and so on...

    this last one shows one of the main problems im encountering. from [0][0] - [1][1] to [0][0] - [2][0], $classes2 changes from 1 to 0. this happens many times of course. just like from [0][0] - [2][0] to [1][1] - [2][0], $classes1 changes from 0 to 1. there could be many many classes, $classes1 and $classes2 could be well above 10. the point is that sometimes $classes1/2 could change from 0 to 5, or from 5 to 2. something like

    [0][0] - [1][4]
    [0][0] - [2][2]
    [1][4] - [2][2]

    so i guess the better way of saying this is, how do i code the behavior of this algorithm? how can i tell it which class it's supposed to check now?
     
  12. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    if you do it in sql, you won't need a looping algorithm... if you do it right, then you should just get a result set back from mySQL and just pop that bad boy in the table. If you post your data-structure, then i can help you with the sql statement
     
  13. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    really?? no loops?? freak yea thats awesome! here im gonna post an image of my data structure.

    [​IMG]


    id is just a number id of each row
    crn is a 5-digit code (in this case it can be regarded as $y)
    code is a 3-character code (like ABC, YUT, etc)
    i think the only other 2 important ones are timeStart and timeEnd, those should be self-explanatory.


    thanks a lot! ur so da man!
     
    Last edited: Aug 12, 2003
  14. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    so.... what is the input to the search? return only class that are in a category or something?
     
  15. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    the search form has two fields: 'code' and 'courseNum'
    and users can enter up to 6 searches

    so you would search ABC 123 and it'll return all times for that class. its a lil more complex than that so ill just post an example:

    'crn' -- 'code' -- 'courseNum' -- 'days' -- 'timeStart' -- 'timeEnd' -- 'P'

    Search result #1 would contain something like:
    12345 -- ABC -- 123 -- MW -- 1200 -- 0200 -- P
    12345 -- ABC -- 123 -- TF -- 1000 -- 1100 -- A
    53486 -- ABC -- 373 -- MWF -- 0800 -- 0900 -- A
    35481 -- ABC -- 385 -- TF -- 0700 -- 0900 -- P

    so as you can see, one class (one crn) can have two different times as in the case of 12345 ABC 123
     
  16. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    AIM me if you're online: ls1sled
     
  17. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    Astro, i think we kinda figured out he'll need to create some sql dynamically in order to find conflicts. I know you're a mySQL expert and i'm not, so i want to bounce this off you.

    I couldn't think of a single-select-statement to find conflicts etc since the user can select multiple classes that they want to see. Basically he has a calendar he wants to display the results in, and if the time range of one class crosses another, then there isn't a way to display that on ONE calendar/table, hence why it should throw an error...

    anyways, i was thinking he could run a prelim sql query which would grab selected classes and their start/end times. Then on the PHP side, loop through that result set once and create a dynamic WHERE clause to find conflicts. Something like this...

    Code:
    FIRST:
    Select CRN, startTime, endTime
    FROM Classes [or whatever]
    Where CRN = 555 or CRN = 44 [etc]
    
    SECOND: [variable are for each row from first query]
    
    SELECT * FROM blah 
    WHERE {dynamic here} ( (startTime BETWEEN [$currStartTime] AND [$currEndTime]) AND CRN != [$currCRN] ) OR ....{/dynamic} 
    
    if the query returned >0 row(s) then there were conflicts. I wasn't sure if there was anything like a TimeSpan object in PHP or mySQL that was usable. If there was, you could put all the classes start and end times in that span, and check for conflicts pretty easily. This is all that i came up with, but it doesn't seem very efficient or portable.

    It's late, i could be completely off lol :uh:
     
  18. babygodzilla

    babygodzilla I love rice

    Joined:
    Nov 5, 2001
    Messages:
    3,108
    Likes Received:
    0
    wait, can we do a SELECT FROM a variable? say we store the result of the first query in $result, so the second one would SELECT FROM $result? or would would the 'blah' be ? :)

    and also, in the first query should the part WHERE CRN = ... OR... be dynamic since we dont know off-hand how many classes a user is searching for
     
    Last edited: Aug 12, 2003
  19. SLED

    SLED build an idiot proof device and someone else will

    Joined:
    Sep 20, 2001
    Messages:
    28,118
    Likes Received:
    0
    Location:
    AZ, like a bauce!
    i don't BELIEVE that is possible. I know in C# and other languages i can do a DataSet.Select( "CRN= '444'" ) or whatever, but i'm not sure about php.

    yeah, i was just being lazy on that first one. Especially because you already have that query working ;)
     
  20. Astro

    Astro Code Monkey

    Joined:
    Mar 18, 2000
    Messages:
    2,047
    Likes Received:
    0
    Location:
    Cleveland Ohio
    Looks like you guys were posting around 3am my time - whew! Sorry I couldn't keep up.

    You guys are definitely on the right track with using a dynamic WHERE clause. Its probably going to get pretty ugly, but then thats why its dynamic.

    It wasn't possible to combine the two queries? All you have to do is tack on the WHERE clause to the 2nd query and make sure all the necessary tables are included properly (either via INNER JOIN or LEFT OUTER JOIN depending on your data layout). I could see issues with multiple duplicate rows and if this is the case, a cleverly crafted GROUP BY might work (depends on how simple the query is).

    If you guys got it to go, thats cool. If not, let me know. I wouldn't mind seeing the PHP code, table definitions, and data if possible (an actual phpMyAdmin table/data export would be cool - but don't post it here).

    You can try catching me on IM: RobSBauer (during the day is really bad time to work on this unless its uber-quick - evenings are best but tonight is not looking too good).
     

Share This Page