I/O Investigation and Pseudo-code of Rational Numbers Notes: 1. If we consider the user interface, we might want to think about how users enter information via keyboard. If the program acts friendly, it must carry more work for itself. Convenience for users might be not simple for programmers. 2. We are aware that users can enter a rational number as an example 123/45. It is a mixed between numbers and characters. Hence it is treated as a string. We must learn how to extract the sub-string before slash and another after slash. Looking for all possible cases with examples will help us do classify this kind of input. I/O Investigation: Input: from keyboard as string. Output: Extract numerator and denominator as integers. Here are the typical cases: Case # Input Expected Output Simplest forms 1 4 14 -2 -7 125 1 -125 1 125 1 125 -12 "ERROR" 2 2 125 -125 125 -125 2 3 4 5 6 "4/14" "-2/-7" "125" "-125" "+125" "+125/-12" "+125/0" 7 7 1 1 1 12 Note 3. In this section, we choose to work from input to Expected Output. The next step from Expected Output to Simplest Forms" can be considered later. This technique of divide and conquer would help us to focus on a narrow solid subject matter. Strategy to handle these cases, pseudo-code: Phase 1: The simplest normal case (Case 2) : StrToNum will convert a string-number to a number. Phase 2: Expension of Phase 1 to cover more cases: Case 3, 4. Theses cases are Case 2 with a sign either + or – in front. Here is the pseudo-code with input as inputString and output as outputNum Pseudocode: StrToInt (input: inputString; output: outputNum) Get the firstChar from inputString Case firstChar is ‘+’: sign is set positive reduce inputString by firstChar ‘-’: sign is set negative reduce inputString by firstChar others: sign is set positive; Do not reduce inputString OutputNum <- call StrToNum(inputString) If sign is negative then outputNum is set to be the negation of outputNum Note 4. The pseudocode is clear enough. However, you should include initialization to help computer language coder to avoid any confusion and difficulty. Positive is a constant to represent ‘+’. Negative is a constant to represent ‘-‘. Sign to be initialized to be positive. You should leave to the coder to choose a way to initialize them. For example, Positive and negative can be implemented as constant of +1 and –1 respectively. Then the line If sign is negative then outputNum is set to be the negation of outputNum, can be coded as outputNum = sign * outputNum; // There will be no if-then statement in this case. Phase 3: Expansion of Phase 2 to cover more cases: Case 1,5, and 6. The new cases have slash ‘/’. If the substring before the slash is extracted, it is numerator in string form (call it stringNum), while the denominator is the remaining after slash (call it stringDenum). The substrings stringNum and stringDenum belong to Phase 2. Here is the pseudocode: input as inputString; output as numerator and denominator. Pseudocode: StrToRational (input: inputString; output: numerator and denominator) Find the position of ‘/’ within the inputString. If position is 0 (zero means no slash) Then // case 2, 3, and 4 { Call StrToInt (inputString, outputNum) and set numerator to be outputNum. Set Denominator to be 1 } Else // case 1, 5, and 6 { Extract all characters before slash and save it into stringNum Extract all characters after slash and save them into stringDenum Call StrToInt (stringNum, outputNum) and set numerator to be outputNum. Call StrToInt (stringDenum, outputNum) and set denomerator to be outputNum. If Denominator is 0 (zero) then send a message ERROR: DIV BY 0 } Note 5: I make these phases less elegant for clarity. As soon as you are familiar with function which receive parameters as input and return output, you can write the pseudo-code in a more elegant form. Here they are: Phase 1: StrToNum(input:stringNum); return value as an integer. Phase 2: Pseudocode: StrToInt (input: inputString) Get the firstChar from inputString Case firstChar is ‘+’: sign positive reduce inputString by firstChar ‘-’: sign negative reduce inputString by firstChar others: sign positive; Do not reduce inputString OutputNum call StrToNum(inputString) If sign is negative then outputNum -outputNum Return outputNum Phase 3: Pseudocode: StrToRational (input: inputString; output: numerator and denominator) Find the position of ‘/’ within the inputString. If position is 0 (zero means no slash) Then // case 2, 3, and 4 { numerator StrToInt (inputString) Set Denominator to be 1 } Else // case 1, 5, and 6 { stringNum inputString[0..position-1] stringDenum inputString[position+1.. length(inputString)] numerator StrToInt (stringNum) denominator StrToInt (stringDenum) If denominator is 0 (zero) then send a message ERROR: DIV BY 0 } Note 6: If you view the entire I/O investigation with the pseudo-code associated with many cases, you will see the calling and called classes. They form into a tree of classes. The calling class will be above its called classes; and each called class can be a calling one of the classes under. This tree of the calling/called classes is named Structure Chart. Note 7: The error messages can be appeared at different classes. Therefore, the messages should be more specific to help you to locate the code section generating the error. In other words, we should not use a common message ERROR for all error cases. In her we have a few places to detect error from the user input via keyboard. In some complex problem, this topic must be investigated thoroughly to have a general view of possible errors.