220 likes | 334 Views
ECE230 Lectures Series. The Art of Design. Ying Wu Electrical & Computer Engineering Northwestern University yingwu@ece.northwestern.edu. Outline. Data flow Top-down vs. bottom-up Coarse to fine Two examples MP#1 MP#2. Data Flow. Data
E N D
ECE230 Lectures Series The Art of Design Ying Wu Electrical & Computer Engineering Northwestern University yingwu@ece.northwestern.edu
Outline • Data flow • Top-down vs. bottom-up • Coarse to fine • Two examples • MP#1 • MP#2
Data Flow • Data • data representation describe your inputs/outputs • E.g. 1: a segment of command line? • E.g. 2: the set of operators? • Inputs and outputs of the building blocks • what are given? • what are expected? • Data flow • blocks are connected through data flow
Flow chart • Coding is a very very small part of programming • design 40% • coding 10% • debugging 50% • When you start to work • always draw flow charts • organize your thoughts by flow charts • use testing cases to validate your flow charts
Top-down • “Incremental” programming • Divide-and-conquer • Task decomposition • No matter how small a task is, you can always divide it into a set of small sequential subtasks • You need to understand your tasks • Focus • Make the structure clear and neat • Always use the basic controls • Sequential • Selection • repetitive
Coarse to Fine • Coarse Fine • Coarse design • determines the structure of the program • tells the basic idea • details are all ignored • concentrate on data flow • Organize it by subtasks • Refinement • A rough “block” can always by replaced by a refined flowchart • It is much easier, because the tasks are simpler
Bottom-up • “Brain-storming” programming • Bottom design • creating a set of small “tools” • thinking based on “basic operations” • Bottom Up • putting tools together • this needs more experiences
“Tools” • Extracting those basic operations • E.g. 1: bypass all “white spaces” • E.g. 2: check digits • Forming functions • inputs • outputs • error checking
Before you start … • Data representation? • How do you represent a “segment”? • st/ed • Your objectives? • Find a segment determine st/ed
End of the string? Command line buffer[500] Y N Find the first element of a seg. done Find the last element of the seg. Start the next segment Copy the segment to piece[100] piece screen A Coarse Design
Code it int main() { cout << “Welcome bla bla bla” << endl; char buffer[500]; cout << "\nInput a command line: "; cin.getline(buffer, 500); char piece[500]; int st = 0, ed = 0; while( buffer[st]!=0 ){ st = _find_the_first_element( ); ed = _find_the_last_element( st ); _copy_segment(piece, st, ed); _display_segment(piece); st = ed + 1; } return 0; }
End of the string? Checking after actions Command line buffer[500] Y N Find the first element of a seg. N Successful? Y Find the last element of the seg. N Start the next segment Successful? Y Copy the segment to piece[100] Error piece screen
Code it int main() { cout << “Welcome bla bla bla” << endl; char buffer[500]; cout << "\nInput a command line: "; cin.getline(buffer, 500); char piece[500]; int st = 0, ed = 0, err_code = 1; while( buffer[st]!=0 ){ st = _find_the_first_element( ); if (buffer[st] == 0) err_code = 0; ed = _find_the_last_element( st ); // err_code can be set inside if (err_code == 0) break; else { _copy_segment(piece, st, ed); _display_segment(piece); st = ed + 1; } } return err_code; }
st st Find the first element of a seg. ‘ ‘ ‘v ‘ ‘ a‘ ‘ r‘ ‘ _‘ ‘ 1‘ ‘ ‘ ‘ ‘ ‘ a‘ ‘ ‘ ‘ +‘ ‘ ‘ ‘3‘ ‘ .‘ ‘ 1‘ ‘ 4‘ ‘ ‘ 0 buffer[0] st Y buffer[st] == ‘ ‘ && buffer[st] != 0 st ++ N st Coarse-to-fine
Is buffer[st] a letter? st ed Find the first element of a seg. init ed = st Is buffer[st] a ‘[‘? Is buffer[st] a digit? Is buffer[st] a ‘:’? Y N Is buffer[st] an operator? Scan to find ed N Y N Y Scan to find ed Y Scan to find ed Y Scan to find ed err_code = 0 Scan to find ed ed and err_code Coarse-to-fine
buffer[st] = ‘[‘ ed Scan to find ed init ed = st+1 buffer[ed] != ‘]’ Conditions for buffer[ed] err_code = 0 break ed ++ Go even finer
Put things together • From coarse-to-fine • always draw flowcharts • keep all your flowchart • Adding things little by little • don’t put together all at once • Validate the new components • whenever you refine a block, always debug it and make sure the whole thing is correct • keep the structure of the program clear
Data Representation (MP#2) • Attention, we only check 4 types of valid grammars. • assignment: "operand_1 = operand_2", e.g., a = 1 • binary operation: "operand_1 operator operand_2", e.g., a + b • unary operation: "operand_1 operator", e.g., a++ • assignment and binary operation: "result = operand_1 operator operand_2", e.g., a = b + c • According to that, we can define • Operations, (e.g., +, -, *, /, ++, --) • Operation types. (e.g., assignment, unary, binary) • So, enum OP {ASN, ADD, MIN, MUL, DIV, INC, DEC}; enum OP_TYPE {asn, unary, binary};
Quit ? Successful? Print version/welcome Y N Command line buffer[500] done Resolve a statement error Y “understand” a statement A Coarse Design
# of pieces result_name operator_name operator_type operand_1 operand_2 Data Flow Resolve a statement ( ) Understand a statement ( ) CL_buffer[] err_code
piece[ ] buffer[ ] Read_a_Piece( ) start_from err_code c c c T/F T/F T/F Is_Char_a_Letter( ) Is_Char_a_Digit( ) Is_Char_a_Operator( ) Tools Use MP#1
Coarse-to-fine • Resolve_a_Statement • T1: scanning to determine the # of pieces • T2: finding operators • T3: grammar check • T4: finding two operands (based on T1/T2) • Understand_a_Statement • Switch/case based on op type • Simply translate and print them out