Qbasicnews.com
December 12, 2019, 06:43:37 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: 1 [2] 3 4
  Print  
Author Topic: Write a bulletproof date validation routine.  (Read 36119 times)
oracle
*/-\*
*****
Posts: 3652



WWW
« Reply #15 on: October 23, 2004, 12:06:11 AM »

Quote from: "ToohTooh"
(5) Take every situation into account. You already did: Your R/LTRIMming was awesome... I never thought it...


In particular, it's a good idea to write as many test cases as possible before writing the actual function/method/class (in whatever language you're coding in). (Black box testing).
Logged

Moneo
Na_th_an
*****
Posts: 1971


« Reply #16 on: October 23, 2004, 10:38:09 PM »

Quote from: "ToohTooh"
Yes, some thoughts from the real world experience...
    NOTICE:
    Code below was **NEVER** tested! I'm bored at the office and compiled this one!.. If possible, debug it and, kindly ask me to edit the post (or, post the correct one)!..[/list]To catch your attention later, list starts off from 2, and this is not a bug -- keep reading! :-D

    Quote
    OUTPUT: The message "VALID" or "INVALID".
    (2) To me, this doesn't necessarily mean the function returning the actual word. If not needed, functions **DO NEVER RETURN STRINGS** (yes, they're like math functions)!.....


    Your remarks about the Valid Invalid strings are true. I used these specific strings to emphasize the result for the challenge. For "real world" as you say, they would return true (-1) or false (0).

    Your remark of "code below was never tested!" completely turned me off regarding any appreciation of your suggested code "improvements".
    *****
    Logged
    Neo
    Na_th_an
    *****
    Posts: 2150



    « Reply #17 on: October 24, 2004, 07:22:15 AM »

    Here's what I made today (in 20 minutes):

    [syntax="QBasic"]DECLARE FUNCTION IsValidDate% (TheDate AS STRING)

    '$DYNAMIC
    DEFINT A-Z

    '+-----------------------------------------------------+
    '| FUNCTION IsValidDate                                |
    '|                                                     |
    '| This function takes a string of 8 characters. This  |
    '| string indicates a specific date in the format      |
    '| YYYYMMDD. In which YYYY must be in the range 1800   |
    '| to 3999. MM must be in the range 01 to 12. And DD   |
    '| must have a leading zero if DD < 10.                |
    '|                                                     |
    '| The function returns -1 if the specific date is a   |
    '| valid date, otherwise it returns 0.                 |
    '|                                                     |
    '| Neo                                                 |
    '+-----------------------------------------------------+
    FUNCTION IsValidDate (TheDate AS STRING)
       'first check for correct input (only numbers, and string must be 8 characters in length)
       TD$ = LTRIM$(RTRIM$(TheDate))
       Allowed$ = "0123456789"
       FOR I = 1 TO LEN(TD$)
          IF INSTR(Allowed$, MID$(TD$, I, 1)) = 0 THEN IsValidDate = 0: EXIT FUNCTION
       NEXT I
       IF LEN(TD$) <> 8 THEN IsValidDate = 0: EXIT FUNCTION

       'check for the year (must be >= 1800 and <= 3999)
       Year = VAL(LEFT$(TD$, 4))
       IF NOT(Year >= 1800 AND Year <= 3999) THEN IsValidDate = 0: EXIT FUNCTION

       'check for the month (must be >= 1 and <= 12)
       Month = VAL(MID$(TD$, 5, 2))
       IF NOT(Month >= 1 AND Month <= 12) THEN IsValidDate = 0: EXIT FUNCTION

       'check if year Year is a leap year
       IsLeapYear = ((Year MOD 4 = 0) AND (Year MOD 100 <> 0)) OR (Year MOD 400 = 0)

       'prepare maxdays variable (numbers of days in the month)
       I = Month
       MaxDays = 30 + ((I + (I > 7)) MOD 2) + 2 * (I = 2) + (I = 2) * IsLeapYear

       'check for the day (must be >= 1 and <= MaxDays)
       Day = VAL(MID$(TD$, 7, 2))
       IF NOT(Day >= 1 AND Day <= MaxDays) THEN IsValidDate = 0: EXIT FUNCTION

       IsValidDate = -1
    END FUNCTION[/syntax]

    I hope it works Wink (I've tested it numerous times and it seems to work Wink)

    Note that this entry was written for clarity. I.e., it could have been done shorter, but I think it's much more clear this way Smiley

    Another note: this entry was created in 20 minutes, without any help from online resources or previously submitted entries.

    Btw, if you like this function to return "VALID" or "INVALID", you could easily make a wrapper:
    [syntax="QBasic"]DECLARE FUNCTION IsValidDateWrapper$ (TheDate AS STRING)

    FUNCTION IsValidDateWrapper$ (TheDate AS STRING)
       IsValidDateWrapper$ = LTRIM$(MID$("IN  ", 2 * ABS(IsValidDate(TheYear)) + 1, 2) + "VALID")
    END FUNCTION
    'note: wrapper not tested but should work Wink[/syntax]

    Also, if you like to see what the short version looks like (the unclear one): Wink
    [syntax="QBasic"]FUNCTION IsValidDate (TheDate AS STRING)
       IsValidDate = 0
       TD$ = LTRIM$(RTRIM$(TheDate))
       FOR I = 1 TO LEN(TD$)
          IF INSTR("0123456789", MID$(TD$, I, 1)) = 0 THEN EXIT FUNCTION
       NEXT I
       IF LEN(TD$) <> 8 THEN EXIT FUNCTION
       IF VAL(LEFT$(TD$, 4)) < 1800 OR VAL(LEFT$(TD$, 4)) > 3999 OR VAL(MID$(TD$, 5, 2)) < 1 OR VAL(MID$(TD$, 5, 2)) > 12 THEN EXIT FUNCTION
       I = VAL(MID$(TD$, 5, 2)) : J = VAL(LEFT$(TD$, 4))
       IF VAL(MID$(TD$, 7, 2)) < 1 OR VAL(MID$(TD$, 7, 2)) > 30 + ((I + (I > 7)) MOD 2) + 2 * (I = 2) + (I = 2) * (((J MOD 4 = 0) AND (J MOD 100 <> 0)) OR (J MOD 400 = 0)) THEN EXIT FUNCTION
       IsValidDate = -1
    END FUNCTION[/syntax]
    Logged
    ToohTooh
    New Member

    Posts: 24



    « Reply #18 on: October 25, 2004, 05:15:25 AM »

    Hello, Moneo.

    You're right on the discouraging header "note (!)" This was 22:30 coding, and, truly speaking, it went the way you saw to mean that I "didn't have a QBasic interpreter at my office computer and, was too lazy and tired to download one!" For the healthiest mind, this was too misleading!

    The remark conflicts with those I have written, but have in mind: My experience doesn't rely on such a simple one.

    Your appreciating "criterias" are another story, and I'm quite shocked that you have been much short sighted: Can a single line stand for the whole? Programming methodology and documenting are different. If you would have spotted some technical places you oppose, and shown relationships of them with your own, we could talk. But, as of yet, there's no point in that.

    And, Meg. Hello!

    I'd like to clarify your concerns about my suggestion numbered (4) by giving a brief understanding of Discrete Maths. This is the area of maths which deals with discrete, unconnected objects, events which we use in analyzing our programming methodology -- that is algorithms, artificial intelligence applications, and so forth. Let me divide this into two to make it more clear:

    (a) Algorithmic thinking: This deals with the ways we use to build unique solutions to the unique problems. My IsAValidDate() is a good example of this, and it is pretty well written: You can subdivide it into discrete sets to understand or test separately [IsALeapYear(), Tokenize()].

    (b) Discrete structures: This deals with the ways we include "others' solutions" to our projects. What are they? Binary trees they are, linked lists they are, hashing they are. On many of them, much discussion have been made, and they are 'de facto' standards in some cases. Please refer to my suggestion numbered (1) of my past post to understand what I mean.

    What is common in (a), and (b)? They let us develop our programming methodologies in a way so that we can examine and analyze them, and represent them in some metrics (Big-O, anyone?).

    So, my efforts on suggesting 'break them down!' aren't just a matter of obsession, but the Computer Science itself.

    Let's say our IsAValidDate() went international to meet different sorting of Date, Month, Year trilogy. If we were to pack everything into a single function, testing and updating it would be tad more painful. Think of giant games, database systems, or operating systems functions!.. But in this case, we only need to update and test result = Tokenize(...) or better, just implement
    Code:
    result = Tokenize(FormatDa$(Da$), ...)
    and only test FormatDa$() to see if it meets our criterias.

    If you are interested, I may suggest you some books on Discrete Maths. But, better, search for them in your favorite searching engine. Even better, go to your local library and find the one which suits you best.

    Glad if I was of some help.
    _____

    Edit history:
    (i) Some spelling corrected.
    Logged

    Don't interrupt me while I'm interrupting." - Winston S. Churchill
    oracle
    */-\*
    *****
    Posts: 3652



    WWW
    « Reply #19 on: October 25, 2004, 08:35:57 PM »

    Quote from: "ToohTooh"
    (Big-O, anyone?).


    Mememe!

    Having said what you did however, creating a whole function to do some very simple algorithm may do nothing more than clutter up the namespace and confuse some people... not so much a problem in object orientated languages however!
    Logged

    Moneo
    Na_th_an
    *****
    Posts: 1971


    « Reply #20 on: October 25, 2004, 11:03:38 PM »

    Quote from: "Neo"
    Here's what I made today (in 20 minutes):.....

    Looks interesting. Give me some time to run a test on it (more than 20 minutes) like I did with Meg's solution. I'll get back to you.
    *****
    Logged
    Moneo
    Na_th_an
    *****
    Posts: 1971


    « Reply #21 on: October 25, 2004, 11:10:55 PM »

    Quote from: "ToohTooh"
    Hello, Moneo......

    ToohTooh,
    Your dissertations are much Tooh much for me. :wink:
    *****
    Logged
    Neo
    Na_th_an
    *****
    Posts: 2150



    « Reply #22 on: October 26, 2004, 06:59:22 AM »

    Moneo:

    Ok Smiley
    Btw:
    [syntax="QBasic"]'prepare maxdays variable (numbers of days in the month)
            I = Month
            MaxDays = 30 + ((I + (I > 7)) MOD 2) + 2 * (I = 2) + (I = 2) * IsLeapYear[/syntax]
    If this piece of code needs some explanation, just tell me Wink
    Logged
    ToohTooh
    New Member

    Posts: 24



    Foo
    « Reply #23 on: October 26, 2004, 02:36:36 PM »

    Let's handle those!..

    Hello, oracle!..
    Quote
    Having said what you did however, creating a whole function to do some very simple algorithm may do nothing more than clutter up the namespace and confuse some people... not so much a problem in object orientated languages however!
    :humm: I think my 'dissertation' wasn't to the point on your side. *Sigh*, and such...

    And, Mexico City!.. Hola!..
    Shocked
    Quote
    ToohTooh,
    Your dissertations are much Tooh much for me. :wink:
    *****
    You are getting on a bit, Moneo. Cheesy
    Logged

    Don't interrupt me while I'm interrupting." - Winston S. Churchill
    Neo
    Na_th_an
    *****
    Posts: 2150



    « Reply #24 on: October 26, 2004, 03:37:14 PM »

    ToohTooh:

    Quote from: "ToohTooh"
    I'd like to clarify your concerns about my suggestion numbered (4) by giving a brief understanding of Discrete Maths. This is the area of maths which deals with discrete, unconnected objects, events which we use in analyzing our programming methodology -- that is algorithms, artificial intelligence applications, and so forth.

    To be exact, Discrete Maths (a part of a.o. Linear Algebra) is the face of maths that deals with functions that cannot be expressed in multiple "normal" maths functions (like +, -, *, /, ^, int, diff, etc). Also, the return value of these discrete functions may differ completely from those in Algebra. Resulting from these 2 statements, we conclude that Discrete Maths cannot be analyzed by standard algebra only. That's why there is Discrete Maths. The easiest example of a discrete formula is:
    Code:
    f(x): x -> INT(x);
    As you can see, this formula cannot be expressed in a normal algebraic formula.
    Using this Discrete Maths, we can now analyze trends without using incredibly difficult algebra. The perfect example for this is trying to find an discrete formula for the amount of days in a specific month of a specific year. Wink This would then look something like this (my code):
    Code:
    f(m, y): m, y -> 30 + ((m + (m > 7)) MOD 2) + 2 * (m = 2) + (m = 2) * (((y MOD 4 = 0) AND (y MOD 100 <> 0)) OR (y MOD 400 = 0))

    Of course, this formula will only be valid from a specific date in the past, as there were severe calendrical changes around year 1600-1700 and earlier.

    Quote from: "ToohTooh"
    (a) Algorithmic thinking: This deals with the ways we use to build unique solutions to the unique problems. My IsAValidDate() is a good example of this, and it is pretty well written: You can subdivide it into discrete sets to understand or test separately [IsALeapYear(), Tokenize()].

    Exactly, but keep in mind that we need not build unique solutions for each unique problem. Many solutions for completely different problems may well suit on a specific other problem.

    Quote from: "ToohTooh"
    (b) Discrete structures: This deals with the ways we include "others' solutions" to our projects. What are they? Binary trees they are, linked lists they are, hashing they are. On many of them, much discussion have been made, and they are 'de facto' standards in some cases. Please refer to my suggestion numbered (1) of my past post to understand what I mean.

    I'd like to make a note about this, correct me if I'm wrong. I think Binary Trees and Linked Lists are no specific solutions to any problem, so I don't think they will fit in as an example. This, as binary trees and linked lists were made in order to accomplish a specific goal using those things. In most cases, binary trees and linked lists are just ways or utilities to accomplish a goal. When cut loose from its purpose-serving environment, Binary Trees and Linked Lists are useless and are no goal on its own.

    Quote from: "ToohTooh"
    So, my efforts on suggesting 'break them down!' aren't just a matter of obsession, but the Computer Science itself.

    Correct. It is essential in any field of computer science (and other) to break apart bigger problems into smaller, easier to solve problems. Of course, many big problems can be split apart in many different ways, and it's the trick to find a way that suits well your needs.

    Quote from: "ToohTooh"
    Let's say our IsAValidDate() went international to meet different sorting of Date, Month, Year trilogy. If we were to pack everything into a single function, testing and updating it would be tad more painful. Think of giant games, database systems, or operating systems functions!.. But in this case, we only need to update and test result = Tokenize(...) or better, just implement
    Code:
    result = Tokenize(FormatDa$(Da$), ...)
    and only test FormatDa$() to see if it meets our criterias.

    Make your functions orthogonal! It's the key in large scale programming. Making your projects this way will save you extremely much hassle later on, either when you need to correct bugs, or when you need to globalize your program (make it accept multiple data formats, often bound to specific countries).
    As said before, the ideal orthogonal function doesn't depend on anything else but itself. In reality though, this ideal goal is often too imaginary to pursue. Try to make it as orthogonal as possible.

    Quote from: "ToohTooh"
    If you are interested, I may suggest you some books on Discrete Maths. But, better, search for them in your favorite searching engine. Even better, go to your local library and find the one which suits you best.

    I have a very good book "The Pragmatic Programmer". It teaches extremely helpful things needed in programming.

    Hope I was a bit useful,

    Neo
    Logged
    oracle
    */-\*
    *****
    Posts: 3652



    WWW
    « Reply #25 on: October 26, 2004, 06:00:56 PM »

    Quote from: "Neo"
    correct me if I'm wrong. I think Binary Trees and Linked Lists are no specific solutions to any problem, so I don't think they will fit in as an example. This, as binary trees and linked lists were made in order to accomplish a specific goal using those things. In most cases, binary trees and linked lists are just ways or utilities to accomplish a goal. When cut loose from its purpose-serving environment, Binary Trees and Linked Lists are useless and are no goal on its own.


    That's like saying the square root function has no use on it's own Wink. The square root function only helps you to accomplish a goal, but by itself it only calculates square roots. Binary trees only help you to accomplish a goal, but by itself only stores data providing log(n) add, search and remove (providing the tree remains height balanced).

    ADTs are a way of storing collections of data, so in a sense they solve the problem of storing collections of data Wink
    Logged

    ToohTooh
    New Member

    Posts: 24



    « Reply #26 on: October 27, 2004, 06:12:11 AM »

      Tin openers, binary trees, and Anatolia Music;
      Car radios, orthogonality, and OO.
    Neo, I like it!..

    Let's take a peek... :wink:

    Quote
    I'd like to make a note about this, correct me if I'm wrong. I think Binary Trees and Linked Lists are no specific solutions to any problem, so I don't think they will fit in as an example. This, as binary trees and linked lists were made in order to accomplish a specific goal using those things. In most cases, binary trees and linked lists are just ways or utilities to accomplish a goal. When cut loose from its purpose-serving environment, Binary Trees and Linked Lists are useless and are no goal on its own.
    Well, no... This is like saying
    Quote
    I have a thing for tin openers; will they teach me how to design one if I am to enroll at Mechanical Engineering?
    When you enroll at mechanical engineering, they won't be teaching you to design a tin opener. But, you will learn 'principles of designing.'

    Binary Trees are just the same: It's your own duty to tailor them to your own needs. Computer Scientists of Turkish Ministry of Culture are designing a virtual 'Music Museum.' Artists will be able to search for matching notes. They are using Patricia Tries. Were scientists thought musical searching through Patricia Tries? Probably not (well, some new programmes have 'Musical Searching' CS courses in Turkey).

    Quote
    Make your functions orthogonal!
    Your intent isn't clearly understood on the 'orthogonal design.' May be you are confused. Did you mean 'orthogonal expansions of recursive functions?' Or, 'orthogonal system design' of software engineering? I was thought some 'orthogonality' in Business Statistics when was in Business School, too. Either case, it would go beyond the scope of this forum.

    'Orthogonally designed software system' is one which enables us to make complex designs feasible and compact. Orthogonality is achieved when technical effects (produced by a component) of modifying the system do not create or propagate side effects to other components of the system. I like it best when orthogonality meets encapsulation of object oriented languages.

    Let's give an example: Does your car's engine start when you turn the radio on? Probably, not: Turning the radio on should influence no system other than the radio itself. System is orthogonal.

    Much software is designed in a non-orthogonal fashion: Even much of Windows. Because, it is very hard to design one orthogonally. Personally, I haven't designed one, either (hey, I'm only 22).

    Some books should occupy the rest!.. Happy reading!..

    Orthogonality:
    The Art of Unix Programming (http://www.faqs.org/docs/artu/).

    Programming methodology in general and programming language theory:
    Concepts in Programming Languages (Cambridge University Press, 2002), and
    Theoretical Aspects of Object-Oriented Programming (MIT Press, 1994).

    Discrete Mathematics:
    (No books at my office -- I'll compile when I get home!)

    Do a related search at:
    http://www.lib.metu.edu.tr/
    http://www.library.itu.edu.tr/
    http://www.library.boun.edu.tr/
    _____

    Edit history:
    (i) Links added, spelling corrected.
    Logged

    Don't interrupt me while I'm interrupting." - Winston S. Churchill
    Meg
    Ancient QBer
    ****
    Posts: 483


    « Reply #27 on: October 27, 2004, 11:11:26 AM »

    ... am I the only person that has absolutely no idea what is going on in this thread?
    Logged
    Neo
    Na_th_an
    *****
    Posts: 2150



    « Reply #28 on: October 27, 2004, 02:12:23 PM »

    Canopeners... music...

    Quote from: "ToohTooh"
    When you enroll at mechanical engineering, they won't be teaching you to design a tin opener. But, you will learn 'principles of designing.'
    Binary Trees are just the same: It's your own duty to tailor them to your own needs. Computer Scientists of Turkish Ministry of Culture are designing a virtual 'Music Museum.' Artists will be able to search for matching notes. They are using Patricia Tries. Were scientists thought musical searching through Patricia Tries? Probably not (well, some new programmes have 'Musical Searching' CS courses in Turkey).

    I noticed my thinking mistake after oracle posted his reply. Sorry about it. (I think I missed some steps in my logical thinking process).

    Quote from: "ToohTooh"
    Your intent isn't clearly understood on the 'orthogonal design.' May be you are confused. Did you mean 'orthogonal expansions of recursive functions?' Or, 'orthogonal system design' of software engineering? I was thought some 'orthogonality' in Business Statistics when was in Business School, too. Either case, it would go beyond the scope of this forum.

    Every time I post "serious" posts like last one, it is preceded by a lot of thinking and logical deduction. I couldn't have possibly been confused, as I clearly have the same definition of orthogonality. The only thing might be that I explained it fuzzy and perhaps even incorrect. Again, sorry.

    The orthogonality principle has much to do with the DRY principle. (DRY stands for "Don't Repeat Yourself"). And the programming rule derived from orthogonality:
    Code:
    PROGRAMMING RULE 13:
    ELIMINATE EFFECTS BETWEEN UNRELATED THINGS
    Design components that are self-contained, independent, and have a single, well-defined purpose.

    (If you want to see more programming rules, just ask or PM me Wink)

    This is my definition of orthogonality:
    Orthogonality is a term borrowed from geometry. In computing, this term has come to signify a kind of independence or decoupling. Two or more things are orthogonal if changes in one do not affect any of the others.

    The perfect example of a non-orthogonal system is an aircraft or helicopter. (Let's talk about aircrafts, I know more about them than about helicopters Wink).
    Each normal aircraft has 3 basic movements, pitch using the elevators, yaw using the rudder and roll/bank using the ailerons. Though it might seem easy to control an airplane, all these movements have side-effects on other controls.
    When you pitch, you speed will change as well, due to the change in angle of attack of the wings (inclination angle).
    When you yaw, the airplane will tend to roll in the opposite direction, due to the fact that the rudder generates a force that will not only generate a moment in the topview axis (y), but also a moment on the longitudinal axis (x).
    And when you roll, the airplane will tend to yaw in the opposite direction, since when you roll, the drag of the far wing increases, which causes the airplane to tilt back around it's topview (y) axis.
    An airplane or helicopter are definitely not orthogonal.

    Orthogonal systems have many advantages (semi-quoted from the TPP book).
    - Gain productivity: changes are localized, development time and testing time are reduced.
    - Orthogonal approach promotes reuse.
    - A subtle gain in productivity.
    Also, orthogonality reduces risk:
    - Diseased sections of code are isolated.
    - The resulting system is less fragile.
    - Orthogonal systems will probably be better tested.

    Quote from: "ToohTooh"
    Much software is designed in a non-orthogonal fashion: Even much of Windows. Because, it is very hard to design one orthogonally. Personally, I haven't designed one, either (hey, I'm only 22)

    I already said something similar in my previous post, and I think it can be stated that very few *real* orthogonal systems have been designed yet, as it is so difficult to make one. As far as I can see, even major software developers have trouble making it as orthogonal as possible.

    Quote from: "ToohTooh"
    Some books should occupy the rest!.. Happy reading!.

    As I said, I already have a good book which almost covers every aspect of projects and programming Wink Btw, I don't really have the time to read books atm Wink

    I hope I was of any use,

    Neo

    ___________________
    Note: This post has been created after thoroughly searching the book "The Pragmatic Programmer. From journeyman to master" by Andrew Hunt and David Thomas.
    ___________________

    Quote from: "Meg"
    ... am I the only person that has absolutely no idea what is going on in this thread?

    Well, I think we're discussing some of the deeper topics of programming Wink
    Logged
    oracle
    */-\*
    *****
    Posts: 3652



    WWW
    « Reply #29 on: October 27, 2004, 06:38:26 PM »

    Orthoganality is like the concept of independence in statistics, as well as a concept from gemotry I think Smiley. Object orientated libraries are a prime example of this - plug it in, read the API documentation, code your use of it. Performance gains using this method are huge Smiley
    Logged

    Pages: 1 [2] 3 4
      Print  
     
    Jump to:  

    Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!