mirror of
				https://github.com/coolaj86/fizzbuzz.git
				synced 2024-11-16 17:29:04 +00:00 
			
		
		
		
	mock census parser for cs 142
This commit is contained in:
		
							parent
							
								
									6a5f859101
								
							
						
					
					
						commit
						86e3d5f76b
					
				
							
								
								
									
										59
									
								
								mock-census/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								mock-census/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | CS 142 Mid-Term 2 (Fall 2010) | ||||||
|  | ==== | ||||||
|  | 
 | ||||||
|  | **Mock Census Parser** | ||||||
|  | 
 | ||||||
|  | Must read a file via HTTP or on the local filesystem. | ||||||
|  | 
 | ||||||
|  | (The file has ostensibly just passed validation and needs no further error-checking) | ||||||
|  | 
 | ||||||
|  | The file contains three newline-delimited directives per block and one EOF directive. | ||||||
|  | 
 | ||||||
|  | Each directive has a number of space-delimited attributes. | ||||||
|  | 
 | ||||||
|  | The directives appear in this order: | ||||||
|  | 
 | ||||||
|  |  * `Head` - this must be the start of the block. Represents the head of household | ||||||
|  |    * name - first name of the individual | ||||||
|  |    * gender | ||||||
|  |    * eye_color | ||||||
|  |    * hair_color | ||||||
|  |    * height - feet as a float | ||||||
|  | 
 | ||||||
|  |  * `Depedent` - 0 or many may exist. Represents children, spouse, etc | ||||||
|  |    * name | ||||||
|  |    * gender | ||||||
|  |    * age - 'minor' or 'adult' | ||||||
|  |    * height | ||||||
|  | 
 | ||||||
|  |  * `End` - must close the block before the next 'Head' | ||||||
|  | 
 | ||||||
|  |  * `SUPER-END` - a special end-of-file (EOF) marker | ||||||
|  |    * `end` MUST precede `SUPER-END` | ||||||
|  | 
 | ||||||
|  | Example Data File | ||||||
|  | ==== | ||||||
|  | 
 | ||||||
|  |     Head Kevin M brown brown 6.15 | ||||||
|  |     Dependent Dagmar F adult 5.9 | ||||||
|  |     Dependent Dorkus M minor 5.7 | ||||||
|  |     End | ||||||
|  |     Head Eve F blue brown 5.5 | ||||||
|  |     Dependent Adam M adult 6.2 | ||||||
|  |     Dependent Fred M minor 6.1 | ||||||
|  |     Dependent Fredwenda F adult 5.3 | ||||||
|  |     End | ||||||
|  |     Head Pentultimus M brown brown 6 | ||||||
|  |     End | ||||||
|  |     Head Beautisha F green red 5.7 | ||||||
|  |     Dependent Bodacious M minor 4.0 | ||||||
|  |     End | ||||||
|  |     SUPER-END | ||||||
|  | 
 | ||||||
|  | Variations from the Spec | ||||||
|  | ==== | ||||||
|  | 
 | ||||||
|  | My implementation is written in JavaScript (which is like LISP, not at all like Java). | ||||||
|  | I take advantage of some JavaScript-isms. | ||||||
|  | 
 | ||||||
|  | In my implementation I also handle `#` comments as well as some extremely minimalistic error-checking. | ||||||
							
								
								
									
										9
									
								
								mock-census/mock-census-test.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								mock-census/mock-census-test.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | # invalid | ||||||
|  | node mock-census.js | ||||||
|  | node mock-census.js files:///path/to/file | ||||||
|  | node mock-census.js httpss://domain.tld/resource | ||||||
|  | # valid | ||||||
|  | node mock-census.js /path/to/file | ||||||
|  | node mock-census.js file:///path/to/file | ||||||
|  | node mock-census.js http://domain.tld/resource | ||||||
|  | node mock-census.js https://domain.tld/resource | ||||||
							
								
								
									
										191
									
								
								mock-census/mock-census.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								mock-census/mock-census.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,191 @@ | |||||||
|  | // TODO parse streaming
 | ||||||
|  | "use strict"; | ||||||
|  | (function (undefined) { | ||||||
|  |   var fs = require('fs'), | ||||||
|  |     url = require('url'), | ||||||
|  |     ahr = require('ahr'), | ||||||
|  |     stream, | ||||||
|  |     node = process.argv[0], | ||||||
|  |     self = process.argv[1], | ||||||
|  |     fulluri = process.argv[2], | ||||||
|  |     uri; | ||||||
|  | 
 | ||||||
|  |   self = self.substr(self.lastIndexOf('/') + 1); | ||||||
|  | 
 | ||||||
|  |   require('remedial'); | ||||||
|  | 
 | ||||||
|  |   function usage() { | ||||||
|  |     console.log("Usage: node {self}".supplant({self: self}) +  | ||||||
|  |       " file:///path/to/file | http://path/to/file"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // Head, and Dependent "Classes"
 | ||||||
|  |   function Comment(lines) { | ||||||
|  |     while (true) { | ||||||
|  |       line = lines.shift(); | ||||||
|  |       if (undefined === line || null === line) { | ||||||
|  |         throw new Error("Expected 'Dependent' or 'end' but reach end-of-file"); | ||||||
|  |       } | ||||||
|  |       if (!line.match(/\s*#/)){ | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return line; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function Dependent(lines) { | ||||||
|  |     var line, dep; | ||||||
|  |     line = Comment(lines); | ||||||
|  |      | ||||||
|  |     if (line.match(/^Dependent\s*/)) { | ||||||
|  |       parts = line.split(/\s+/); | ||||||
|  |       dep = { | ||||||
|  |         // no error checking in spec
 | ||||||
|  |         name: parts[1], | ||||||
|  |         gender: parts[2], | ||||||
|  |         age: parts[3], | ||||||
|  |         height: parseInt(parts[4], 10), | ||||||
|  |       }; | ||||||
|  |     } else if (line.match(/^End\s*/)) { | ||||||
|  |       return false; | ||||||
|  |     } else { | ||||||
|  |       throw new Error("Expected 'Dependent' or 'End' but saw\n    " + line.substr(0,20)); | ||||||
|  |     } | ||||||
|  |     return dep; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function Head(lines) { | ||||||
|  |     var line, head, parts, dep; | ||||||
|  |     line = Comment(lines); | ||||||
|  | 
 | ||||||
|  |     if (line.match(/^Head\s*/)) { | ||||||
|  |       parts = line.split(/\s+/); | ||||||
|  |       head = { | ||||||
|  |         // no error checking in spec
 | ||||||
|  |         name: parts[1], | ||||||
|  |         gender: parts[2], | ||||||
|  |         eye_color: parts[3], | ||||||
|  |         hair_color: parts[4], | ||||||
|  |         height: parseInt(parts[5], 10), | ||||||
|  |         deps: [] | ||||||
|  |       }; | ||||||
|  |       while (dep = Dependent(lines)) { | ||||||
|  |         head.deps.push(dep); | ||||||
|  |       } | ||||||
|  |     } else if (line.match(/^SUPER-END\s*/)) { | ||||||
|  |       return false; | ||||||
|  |     } else { | ||||||
|  |         throw new Error("Expected 'Head' or 'SUPER-END' but saw\n    " + line.substr(0,20)); | ||||||
|  |     } | ||||||
|  |     return head; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function readFile(file) { | ||||||
|  |     var promise = require('futures').promise(), | ||||||
|  |       stream, | ||||||
|  |       data = new Buffer(''); | ||||||
|  | 
 | ||||||
|  |     stream = fs.createReadStream(file, { flags: 'r' }); | ||||||
|  |     stream.on('error', function (err) { | ||||||
|  |       promise.fulfill(err, stream, data); | ||||||
|  |     }); | ||||||
|  |     stream.on('data', function (chunk) { | ||||||
|  |       data += chunk; | ||||||
|  |     }); | ||||||
|  |     stream.on('end', function () { | ||||||
|  |       promise.fulfill(undefined, stream, data); | ||||||
|  |     }); | ||||||
|  |     return promise; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Queries
 | ||||||
|  | 
 | ||||||
|  |   // Average height of Heads of Household
 | ||||||
|  |   function query1(heads) { | ||||||
|  |     var heights = 0.0; | ||||||
|  |     heads.forEach(function (head) { | ||||||
|  |       heights += head.height; | ||||||
|  |     }); | ||||||
|  |     console.log("Average Height of Heads of Household: " + (heights / heads.length)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // What is the height of the tallest of all dependents?
 | ||||||
|  |   function query2(heads) { | ||||||
|  |     var max = 0.0; | ||||||
|  |     heads.forEach(function (head) { | ||||||
|  |       head.deps.forEach(function (dep) { | ||||||
|  |         max = Math.max(max, dep.height); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     console.log("Height of tallest Dependent: " + max); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // The height of the shortest Dependent of a female Head of Household
 | ||||||
|  |   function query3(heads) { | ||||||
|  |     var min = Infinity; | ||||||
|  |     heads.forEach(function (head) { | ||||||
|  |       if ('F' !== head.gender) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       head.deps.forEach(function (dep) { | ||||||
|  |         min = Math.min(min, dep.height); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     console.log("Height of shortest Dependent of a Female-Headed Household: " + min); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Average height of male dependents of brown-haired male heads of houshold
 | ||||||
|  |   function query4(heads) { | ||||||
|  |     var heights = 0.0, count = 0; | ||||||
|  |     heads.forEach(function (head) { | ||||||
|  |       if ('m' !== head.gender && 'brown' !== head.hair_color) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       head.deps.forEach(function (dep) { | ||||||
|  |         count += 1; | ||||||
|  |         heights += dep.height; | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     console.log("Average height of male dependent of brown-haired male Heads of Household: " + (heights / count)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function parseData(err, x, data) { | ||||||
|  |     var lines = data.split('\n'), | ||||||
|  |       heads = [], | ||||||
|  |       curHead; | ||||||
|  | 
 | ||||||
|  |     while (curHead = Head(lines)) { | ||||||
|  |       heads.push(curHead); | ||||||
|  |     } | ||||||
|  |     console.log(JSON.stringify(heads, null, '  ')); | ||||||
|  |     query1(heads); | ||||||
|  |     query2(heads); | ||||||
|  |     query3(heads); | ||||||
|  |     query4(heads); | ||||||
|  |     return heads; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function main() { | ||||||
|  |     if (!fulluri) { | ||||||
|  |       usage(); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |        | ||||||
|  |     uri = url.parse(fulluri, true); | ||||||
|  |     if (!uri.protocol) { | ||||||
|  |       uri.protocol = ''; | ||||||
|  |     } | ||||||
|  |     if ('file:' === uri.protocol || '' === uri.protocol) { | ||||||
|  |       readFile(uri.pathname).when(parseData); | ||||||
|  |     } else if (uri.protocol.match(/^http[s]?:$/)) { | ||||||
|  |       ahr.get(fulluri).when(parseData); | ||||||
|  |     } else { | ||||||
|  |       usage(); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   main(); | ||||||
|  | 
 | ||||||
|  | }()); | ||||||
							
								
								
									
										19
									
								
								mock-census/mock-census.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								mock-census/mock-census.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | #Head First Gender Eye-color Hair-color Height (exactly one per block) | ||||||
|  | Head Kevin M brown brown 6.15 | ||||||
|  | #Dependent First Gender Age Height (0 or more per block) | ||||||
|  | Dependent Dagmar F adult 5.9 | ||||||
|  | Dependent Dorkus M minor 5.7 | ||||||
|  | #End end-of-block | ||||||
|  | End | ||||||
|  | Head Eve F blue brown 5.5 | ||||||
|  | Dependent Adam M adult 6.2 | ||||||
|  | Dependent Fred M minor 6.1 | ||||||
|  | Dependent Fredwenda F adult 5.3 | ||||||
|  | End | ||||||
|  | Head Pentultimus M brown brown 6 | ||||||
|  | End | ||||||
|  | Head Beautisha F green red 5.7 | ||||||
|  | Dependent Bodacious M minor 4.0 | ||||||
|  | End | ||||||
|  | #SUPER-END end-of-file | ||||||
|  | SUPER-END | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user