diff --git a/elm.json b/elm.json index 1bf0b5cfc35f45cb205a7fcc07315397d8b7f5a2..602a6f86b0c1ea82f21adc40d52a5b4405b201ec 100644 --- a/elm.json +++ b/elm.json @@ -6,6 +6,7 @@ "elm-version": "0.19.1", "dependencies": { "direct": { + "BrianHicks/elm-csv": "4.0.1", "NoRedInk/elm-json-decode-pipeline": "1.0.1", "avh4/elm-color": "1.0.0", "elm/browser": "1.0.2", @@ -16,7 +17,6 @@ "elm-community/graph": "6.0.0", "elm-community/list-extra": "8.7.0", "elm-community/typed-svg": "7.0.0", - "ericgj/elm-csv-decode": "2.0.1", "folkertdev/one-true-path-experiment": "6.0.0", "gampleman/elm-visualization": "2.4.1", "lovasoa/elm-csv": "1.1.7", @@ -52,7 +52,8 @@ "justinmimbs/time-extra": "1.2.0", "robinheghan/murmur3": "1.0.0", "rtfeldman/elm-hex": "1.0.0", - "ryan-haskell/date-format": "1.0.0" + "ryan-haskell/date-format": "1.0.0", + "ericgj/elm-csv-decode": "2.0.1" } }, "test-dependencies": { diff --git a/public/csv/smartphone_dataset.csv b/public/csv/smartphone_dataset.csv index 19e51692bd0a8a95faf7f072d5c7b6d02166675b..04d6208a9e2e768061d867968aad2d80f3db2d0f 100644 --- a/public/csv/smartphone_dataset.csv +++ b/public/csv/smartphone_dataset.csv @@ -1,4 +1,4 @@ -,index,brand,model,price,rating,5G,NFC,IR_blaster,processor_name,processor_brand,num_cores,processor_speed,ram,Battery,fast_charging,Internal_mem,RAM,display,screen_size,resolution,refresh_rate,camera,card,os +id,index,brand,model,price,rating,5G,NFC,IR_blaster,processor_name,processor_brand,num_cores,processor_speed,ram,Battery,fast_charging,Internal_mem,RAM,display,screen_size,resolution,refresh_rate,camera,card,os 0,2,oneplus,OnePlus 11 5G,54999,89.0,True,True,False,Snapdragon 8 Gen2,snapdragon,octa core, 3.2 GHz Processor,"12 GB RAM, 256 GB inbuilt",5000.0,100, 256 GB inbuilt,12,"6.7 inches, 1440 x 3216 px, 120 Hz Display with Punch Hole",6.7 inches,1440 x 3216 ,120,50 MP + 48 MP + 32 MP Triple Rear & 16 MP Front Camera,Memory Card Not Supported,Android v13 1,3,oneplus,OnePlus Nord CE 2 Lite 5G,19989,81.0,True,False,False,Snapdragon 695,snapdragon,octa core, 2.2 GHz Processor,"6 GB RAM, 128 GB inbuilt",5000.0,33, 128 GB inbuilt,6,"6.59 inches, 1080 x 2412 px, 120 Hz Display with Punch Hole",6.59 inches,1080 x 2412 ,120,64 MP + 2 MP + 2 MP Triple Rear & 16 MP Front Camera,"Memory Card (Hybrid), upto 1 TB",Android v12 2,4,samsung,Samsung Galaxy A14 5G,16499,75.0,True,False,False,Exynos 1330,exynos,octa core, 2.4 GHz Processor,"4 GB RAM, 64 GB inbuilt",5000.0,15, 64 GB inbuilt,4,"6.6 inches, 1080 x 2408 px, 90 Hz Display with Water Drop Notch",6.6 inches,1080 x 2408 ,90,50 MP + 2 MP + 2 MP Triple Rear & 13 MP Front Camera,"Memory Card Supported, upto 1 TB",Android v13 diff --git a/public/main.js b/public/main.js index 26913da1d67211e17f54b5d2ec9a5349efb5b0f5..d4b73307bcdb86331305056c8bf40a8cb56d2296 100644 --- a/public/main.js +++ b/public/main.js @@ -6174,21 +6174,819 @@ var $author$project$Main$subscriptions = function (_v0) { }; var $elm$core$Platform$Cmd$batch = _Platform_batch; var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); -var $elm$core$String$lines = _String_lines; -var $author$project$Main$Smartphone = F8( - function (id, brand, model, price, rating, g5, nfc, ir_blaster) { - return {brand: brand, g5: g5, id: id, ir_blaster: ir_blaster, model: model, nfc: nfc, price: price, rating: rating}; +var $BrianHicks$elm_csv$Csv$Decode$FieldNamesFromFirstRow = {$: 'FieldNamesFromFirstRow'}; +var $BrianHicks$elm_csv$Csv$Decode$ParsingError = function (a) { + return {$: 'ParsingError', a: a}; +}; +var $elm$core$Result$andThen = F2( + function (callback, result) { + if (result.$ === 'Ok') { + var value = result.a; + return callback(value); + } else { + var msg = result.a; + return $elm$core$Result$Err(msg); + } }); -var $elm$core$List$filter = F2( - function (isGood, list) { - return A3( - $elm$core$List$foldr, - F2( - function (x, xs) { - return isGood(x) ? A2($elm$core$List$cons, x, xs) : xs; - }), +var $BrianHicks$elm_csv$Csv$Decode$DecodingErrors = function (a) { + return {$: 'DecodingErrors', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$OnlyColumn_ = {$: 'OnlyColumn_'}; +var $elm$core$Basics$composeL = F3( + function (g, f, x) { + return g( + f(x)); + }); +var $elm$core$List$append = F2( + function (xs, ys) { + if (!ys.b) { + return xs; + } else { + return A3($elm$core$List$foldr, $elm$core$List$cons, ys, xs); + } + }); +var $elm$core$List$concat = function (lists) { + return A3($elm$core$List$foldr, $elm$core$List$append, _List_Nil, lists); +}; +var $BrianHicks$elm_csv$Csv$Decode$NoFieldNamesOnFirstRow = {$: 'NoFieldNamesOnFirstRow'}; +var $elm$core$String$trim = _String_trim; +var $BrianHicks$elm_csv$Csv$Decode$getFieldNames = F2( + function (headers, rows) { + var fromList = function (names) { + return A3( + $elm$core$List$foldl, + F2( + function (name, _v2) { + var soFar = _v2.a; + var i = _v2.b; + return _Utils_Tuple2( + A3($elm$core$Dict$insert, name, i, soFar), + i + 1); + }), + _Utils_Tuple2($elm$core$Dict$empty, 0), + names).a; + }; + switch (headers.$) { + case 'NoFieldNames': + return $elm$core$Result$Ok( + _Utils_Tuple3( + {available: false, names: $elm$core$Dict$empty}, + 0, + rows)); + case 'CustomFieldNames': + var names = headers.a; + return $elm$core$Result$Ok( + _Utils_Tuple3( + { + available: true, + names: fromList(names) + }, + 0, + rows)); + default: + if (!rows.b) { + return $elm$core$Result$Err($BrianHicks$elm_csv$Csv$Decode$NoFieldNamesOnFirstRow); + } else { + var first = rows.a; + var rest = rows.b; + return $elm$core$Result$Ok( + _Utils_Tuple3( + { + available: true, + names: fromList( + A2($elm$core$List$map, $elm$core$String$trim, first)) + }, + 1, + rest)); + } + } + }); +var $elm$core$Result$map = F2( + function (func, ra) { + if (ra.$ === 'Ok') { + var a = ra.a; + return $elm$core$Result$Ok( + func(a)); + } else { + var e = ra.a; + return $elm$core$Result$Err(e); + } + }); +var $BrianHicks$elm_csv$Csv$Decode$applyDecoder = F3( + function (fieldNames, _v0, allRows) { + var decode = _v0.a; + var defaultLocation = $BrianHicks$elm_csv$Csv$Decode$OnlyColumn_; + return A2( + $elm$core$Result$andThen, + function (_v1) { + var resolvedNames = _v1.a; + var firstRowNumber = _v1.b; + var rows = _v1.c; + return A2( + $elm$core$Result$mapError, + A2( + $elm$core$Basics$composeL, + A2($elm$core$Basics$composeL, $BrianHicks$elm_csv$Csv$Decode$DecodingErrors, $elm$core$List$concat), + $elm$core$List$reverse), + A2( + $elm$core$Result$map, + $elm$core$List$reverse, + A3( + $elm$core$List$foldl, + F2( + function (row, _v2) { + var soFar = _v2.a; + var rowNum = _v2.b; + return _Utils_Tuple2( + function () { + var _v3 = A4(decode, defaultLocation, resolvedNames, rowNum, row); + if (_v3.$ === 'Ok') { + var val = _v3.a; + if (soFar.$ === 'Ok') { + var values = soFar.a; + return $elm$core$Result$Ok( + A2($elm$core$List$cons, val, values)); + } else { + var errs = soFar.a; + return $elm$core$Result$Err(errs); + } + } else { + var err = _v3.a; + if (soFar.$ === 'Ok') { + return $elm$core$Result$Err( + _List_fromArray( + [err])); + } else { + var errs = soFar.a; + return $elm$core$Result$Err( + A2($elm$core$List$cons, err, errs)); + } + } + }(), + rowNum + 1); + }), + _Utils_Tuple2( + $elm$core$Result$Ok(_List_Nil), + firstRowNumber), + rows).a)); + }, + A2($BrianHicks$elm_csv$Csv$Decode$getFieldNames, fieldNames, allRows)); + }); +var $BrianHicks$elm_csv$Csv$Parser$AdditionalCharactersAfterClosingQuote = function (a) { + return {$: 'AdditionalCharactersAfterClosingQuote', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Parser$SourceEndedWithoutClosingQuote = function (a) { + return {$: 'SourceEndedWithoutClosingQuote', a: a}; +}; +var $elm$core$String$cons = _String_cons; +var $elm$core$String$fromChar = function (_char) { + return A2($elm$core$String$cons, _char, ''); +}; +var $elm$core$Basics$ge = _Utils_ge; +var $BrianHicks$elm_csv$Csv$Parser$parse = F2( + function (config, source) { + var finalLength = $elm$core$String$length(source); + var parseQuotedField = F4( + function (isFieldSeparator, soFar, startOffset, endOffset) { + parseQuotedField: + while (true) { + if ((endOffset - finalLength) >= 0) { + return $elm$core$Result$Err($BrianHicks$elm_csv$Csv$Parser$SourceEndedWithoutClosingQuote); + } else { + if (A3($elm$core$String$slice, endOffset, endOffset + 1, source) === '\"') { + var segment = A3($elm$core$String$slice, startOffset, endOffset, source); + if (((endOffset + 1) - finalLength) >= 0) { + return $elm$core$Result$Ok( + _Utils_Tuple3( + _Utils_ap(soFar, segment), + endOffset + 1, + false)); + } else { + var next = A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source); + if (next === '\"') { + var newPos = endOffset + 2; + var $temp$isFieldSeparator = isFieldSeparator, + $temp$soFar = soFar + (segment + '\"'), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + isFieldSeparator = $temp$isFieldSeparator; + soFar = $temp$soFar; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseQuotedField; + } else { + if (isFieldSeparator(next)) { + return $elm$core$Result$Ok( + _Utils_Tuple3( + _Utils_ap(soFar, segment), + endOffset + 2, + false)); + } else { + if (next === '\n') { + return $elm$core$Result$Ok( + _Utils_Tuple3( + _Utils_ap(soFar, segment), + endOffset + 2, + true)); + } else { + if ((next === '\u000D') && (A3($elm$core$String$slice, endOffset + 2, endOffset + 3, source) === '\n')) { + return $elm$core$Result$Ok( + _Utils_Tuple3( + _Utils_ap(soFar, segment), + endOffset + 3, + true)); + } else { + return $elm$core$Result$Err($BrianHicks$elm_csv$Csv$Parser$AdditionalCharactersAfterClosingQuote); + } + } + } + } + } + } else { + var $temp$isFieldSeparator = isFieldSeparator, + $temp$soFar = soFar, + $temp$startOffset = startOffset, + $temp$endOffset = endOffset + 1; + isFieldSeparator = $temp$isFieldSeparator; + soFar = $temp$soFar; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseQuotedField; + } + } + } + }); + var parseComma = F4( + function (row, rows, startOffset, endOffset) { + parseComma: + while (true) { + if ((endOffset - finalLength) >= 0) { + var finalField = A3($elm$core$String$slice, startOffset, endOffset, source); + return ((finalField === '') && _Utils_eq(row, _List_Nil)) ? $elm$core$Result$Ok( + $elm$core$List$reverse(rows)) : $elm$core$Result$Ok( + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, finalField, row)), + rows))); + } else { + var first = A3($elm$core$String$slice, endOffset, endOffset + 1, source); + if (first === ',') { + var newPos = endOffset + 1; + var $temp$row = A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row), + $temp$rows = rows, + $temp$startOffset = newPos, + $temp$endOffset = newPos; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseComma; + } else { + if (first === '\n') { + var newPos = endOffset + 1; + var $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row)), + rows), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseComma; + } else { + if ((first === '\u000D') && (A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source) === '\n')) { + var newPos = endOffset + 2; + var $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row)), + rows), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseComma; + } else { + if (first === '\"') { + var newPos = endOffset + 1; + var _v0 = A4( + parseQuotedField, + function (c) { + return c === ','; + }, + '', + newPos, + newPos); + if (_v0.$ === 'Ok') { + var _v1 = _v0.a; + var value = _v1.a; + var afterQuotedField = _v1.b; + var rowEnded = _v1.c; + if (_Utils_cmp(afterQuotedField, finalLength) > -1) { + return $elm$core$Result$Ok( + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, value, row)), + rows))); + } else { + if (rowEnded) { + var $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, value, row)), + rows), + $temp$startOffset = afterQuotedField, + $temp$endOffset = afterQuotedField; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseComma; + } else { + var $temp$row = A2($elm$core$List$cons, value, row), + $temp$rows = rows, + $temp$startOffset = afterQuotedField, + $temp$endOffset = afterQuotedField; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseComma; + } + } + } else { + var problem = _v0.a; + return $elm$core$Result$Err( + problem( + $elm$core$List$length(rows) + 1)); + } + } else { + var $temp$row = row, + $temp$rows = rows, + $temp$startOffset = startOffset, + $temp$endOffset = endOffset + 1; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseComma; + } + } + } + } + } + } + }); + var parseHelp = F5( + function (isFieldSeparator, row, rows, startOffset, endOffset) { + parseHelp: + while (true) { + if ((endOffset - finalLength) >= 0) { + var finalField = A3($elm$core$String$slice, startOffset, endOffset, source); + return ((finalField === '') && _Utils_eq(row, _List_Nil)) ? $elm$core$Result$Ok( + $elm$core$List$reverse(rows)) : $elm$core$Result$Ok( + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, finalField, row)), + rows))); + } else { + var first = A3($elm$core$String$slice, endOffset, endOffset + 1, source); + if (isFieldSeparator(first)) { + var newPos = endOffset + 1; + var $temp$isFieldSeparator = isFieldSeparator, + $temp$row = A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row), + $temp$rows = rows, + $temp$startOffset = newPos, + $temp$endOffset = newPos; + isFieldSeparator = $temp$isFieldSeparator; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseHelp; + } else { + if (first === '\n') { + var newPos = endOffset + 1; + var $temp$isFieldSeparator = isFieldSeparator, + $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row)), + rows), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + isFieldSeparator = $temp$isFieldSeparator; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseHelp; + } else { + if ((first === '\u000D') && (A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source) === '\n')) { + var newPos = endOffset + 2; + var $temp$isFieldSeparator = isFieldSeparator, + $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row)), + rows), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + isFieldSeparator = $temp$isFieldSeparator; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseHelp; + } else { + if (first === '\"') { + var newPos = endOffset + 1; + var _v2 = A4(parseQuotedField, isFieldSeparator, '', newPos, newPos); + if (_v2.$ === 'Ok') { + var _v3 = _v2.a; + var value = _v3.a; + var afterQuotedField = _v3.b; + var rowEnded = _v3.c; + if (_Utils_cmp(afterQuotedField, finalLength) > -1) { + return $elm$core$Result$Ok( + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, value, row)), + rows))); + } else { + if (rowEnded) { + var $temp$isFieldSeparator = isFieldSeparator, + $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, value, row)), + rows), + $temp$startOffset = afterQuotedField, + $temp$endOffset = afterQuotedField; + isFieldSeparator = $temp$isFieldSeparator; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseHelp; + } else { + var $temp$isFieldSeparator = isFieldSeparator, + $temp$row = A2($elm$core$List$cons, value, row), + $temp$rows = rows, + $temp$startOffset = afterQuotedField, + $temp$endOffset = afterQuotedField; + isFieldSeparator = $temp$isFieldSeparator; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseHelp; + } + } + } else { + var problem = _v2.a; + return $elm$core$Result$Err( + problem( + $elm$core$List$length(rows) + 1)); + } + } else { + var $temp$isFieldSeparator = isFieldSeparator, + $temp$row = row, + $temp$rows = rows, + $temp$startOffset = startOffset, + $temp$endOffset = endOffset + 1; + isFieldSeparator = $temp$isFieldSeparator; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseHelp; + } + } + } + } + } + } + }); + var parseSemicolon = F4( + function (row, rows, startOffset, endOffset) { + parseSemicolon: + while (true) { + if ((endOffset - finalLength) >= 0) { + var finalField = A3($elm$core$String$slice, startOffset, endOffset, source); + return ((finalField === '') && _Utils_eq(row, _List_Nil)) ? $elm$core$Result$Ok( + $elm$core$List$reverse(rows)) : $elm$core$Result$Ok( + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, finalField, row)), + rows))); + } else { + var first = A3($elm$core$String$slice, endOffset, endOffset + 1, source); + if (first === ';') { + var newPos = endOffset + 1; + var $temp$row = A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row), + $temp$rows = rows, + $temp$startOffset = newPos, + $temp$endOffset = newPos; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseSemicolon; + } else { + if (first === '\n') { + var newPos = endOffset + 1; + var $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row)), + rows), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseSemicolon; + } else { + if ((first === '\u000D') && (A3($elm$core$String$slice, endOffset + 1, endOffset + 2, source) === '\n')) { + var newPos = endOffset + 2; + var $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + A3($elm$core$String$slice, startOffset, endOffset, source), + row)), + rows), + $temp$startOffset = newPos, + $temp$endOffset = newPos; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseSemicolon; + } else { + if (first === '\"') { + var newPos = endOffset + 1; + var _v4 = A4( + parseQuotedField, + function (c) { + return c === ';'; + }, + '', + newPos, + newPos); + if (_v4.$ === 'Ok') { + var _v5 = _v4.a; + var value = _v5.a; + var afterQuotedField = _v5.b; + var rowEnded = _v5.c; + if (_Utils_cmp(afterQuotedField, finalLength) > -1) { + return $elm$core$Result$Ok( + $elm$core$List$reverse( + A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, value, row)), + rows))); + } else { + if (rowEnded) { + var $temp$row = _List_Nil, + $temp$rows = A2( + $elm$core$List$cons, + $elm$core$List$reverse( + A2($elm$core$List$cons, value, row)), + rows), + $temp$startOffset = afterQuotedField, + $temp$endOffset = afterQuotedField; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseSemicolon; + } else { + var $temp$row = A2($elm$core$List$cons, value, row), + $temp$rows = rows, + $temp$startOffset = afterQuotedField, + $temp$endOffset = afterQuotedField; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseSemicolon; + } + } + } else { + var problem = _v4.a; + return $elm$core$Result$Err( + problem( + $elm$core$List$length(rows) + 1)); + } + } else { + var $temp$row = row, + $temp$rows = rows, + $temp$startOffset = startOffset, + $temp$endOffset = endOffset + 1; + row = $temp$row; + rows = $temp$rows; + startOffset = $temp$startOffset; + endOffset = $temp$endOffset; + continue parseSemicolon; + } + } + } + } + } + } + }); + var fieldSeparator = $elm$core$String$fromChar(config.fieldSeparator); + return $elm$core$String$isEmpty(source) ? $elm$core$Result$Ok(_List_Nil) : (_Utils_eq( + config.fieldSeparator, + _Utils_chr(',')) ? A4(parseComma, _List_Nil, _List_Nil, 0, 0) : (_Utils_eq( + config.fieldSeparator, + _Utils_chr(';')) ? A4(parseSemicolon, _List_Nil, _List_Nil, 0, 0) : A5( + parseHelp, + function (s) { + return _Utils_eq(s, fieldSeparator); + }, _List_Nil, - list); + _List_Nil, + 0, + 0))); + }); +var $BrianHicks$elm_csv$Csv$Decode$decodeCustom = F4( + function (config, fieldNames, decoder, source) { + return A2( + $elm$core$Result$andThen, + A2($BrianHicks$elm_csv$Csv$Decode$applyDecoder, fieldNames, decoder), + A2( + $elm$core$Result$mapError, + $BrianHicks$elm_csv$Csv$Decode$ParsingError, + A2($BrianHicks$elm_csv$Csv$Parser$parse, config, source))); + }); +var $BrianHicks$elm_csv$Csv$Decode$decodeCsv = $BrianHicks$elm_csv$Csv$Decode$decodeCustom( + { + fieldSeparator: _Utils_chr(',') + }); +var $author$project$Main$Smartphone = function (id) { + return function (brand) { + return function (model) { + return function (price) { + return function (rating) { + return function (g5) { + return function (nfc) { + return function (ir_blaster) { + return function (processor_name) { + return function (processor_brand) { + return function (num_cors) { + return function (processor_speed) { + return function (battery) { + return function (fast_charging) { + return function (memory) { + return function (ram) { + return function (screen_size) { + return function (resolution) { + return function (refresh_rate) { + return function (camera) { + return function (card) { + return function (os) { + return {battery: battery, brand: brand, camera: camera, card: card, fast_charging: fast_charging, g5: g5, id: id, ir_blaster: ir_blaster, memory: memory, model: model, nfc: nfc, num_cors: num_cors, os: os, price: price, processor_brand: processor_brand, processor_name: processor_name, processor_speed: processor_speed, ram: ram, rating: rating, refresh_rate: refresh_rate, resolution: resolution, screen_size: screen_size}; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +}; +var $BrianHicks$elm_csv$Csv$Decode$Decoder = function (a) { + return {$: 'Decoder', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$andThen = F2( + function (next, _v0) { + var first = _v0.a; + return $BrianHicks$elm_csv$Csv$Decode$Decoder( + F4( + function (location, fieldNames, rowNum, row) { + return A2( + $elm$core$Result$andThen, + function (nextValue) { + var _v1 = next(nextValue); + var _final = _v1.a; + return A4(_final, location, fieldNames, rowNum, row); + }, + A4(first, location, fieldNames, rowNum, row)); + })); + }); +var $BrianHicks$elm_csv$Csv$Decode$map = F2( + function (transform, _v0) { + var decoder = _v0.a; + return $BrianHicks$elm_csv$Csv$Decode$Decoder( + F4( + function (location, fieldNames, rowNum, row) { + return A2( + $elm$core$Result$map, + transform, + A4(decoder, location, fieldNames, rowNum, row)); + })); + }); +var $BrianHicks$elm_csv$Csv$Decode$ColumnNotFound = function (a) { + return {$: 'ColumnNotFound', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$ExpectedOneColumn = function (a) { + return {$: 'ExpectedOneColumn', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$FieldDecodingError = function (a) { + return {$: 'FieldDecodingError', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$FieldNotFound = function (a) { + return {$: 'FieldNotFound', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$FieldNotProvided = function (a) { + return {$: 'FieldNotProvided', a: a}; +}; +var $elm$core$List$drop = F2( + function (n, list) { + drop: + while (true) { + if (n <= 0) { + return list; + } else { + if (!list.b) { + return list; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs; + n = $temp$n; + list = $temp$list; + continue drop; + } + } + } }); var $elm$core$List$head = function (list) { if (list.b) { @@ -6199,59 +6997,460 @@ var $elm$core$List$head = function (list) { return $elm$core$Maybe$Nothing; } }; +var $BrianHicks$elm_csv$Csv$Decode$Column = function (a) { + return {$: 'Column', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$Field = F2( + function (a, b) { + return {$: 'Field', a: a, b: b}; + }); +var $BrianHicks$elm_csv$Csv$Decode$OnlyColumn = {$: 'OnlyColumn'}; +var $BrianHicks$elm_csv$Csv$Decode$locationToColumn = F2( + function (fieldNames, location) { + switch (location.$) { + case 'Column_': + var i = location.a; + return $BrianHicks$elm_csv$Csv$Decode$Column(i); + case 'Field_': + var name = location.a; + return A2( + $BrianHicks$elm_csv$Csv$Decode$Field, + name, + A2($elm$core$Dict$get, name, fieldNames)); + default: + return $BrianHicks$elm_csv$Csv$Decode$OnlyColumn; + } + }); +var $BrianHicks$elm_csv$Csv$Decode$fromString = function (convert) { + return $BrianHicks$elm_csv$Csv$Decode$Decoder( + F4( + function (location, _v0, rowNum, row) { + var names = _v0.names; + var error = function (problem) { + return $elm$core$Result$Err( + _List_fromArray( + [ + $BrianHicks$elm_csv$Csv$Decode$FieldDecodingError( + { + column: A2($BrianHicks$elm_csv$Csv$Decode$locationToColumn, names, location), + problem: problem, + row: rowNum + }) + ])); + }; + switch (location.$) { + case 'Column_': + var colNum = location.a; + var _v2 = $elm$core$List$head( + A2($elm$core$List$drop, colNum, row)); + if (_v2.$ === 'Just') { + var value = _v2.a; + var _v3 = convert(value); + if (_v3.$ === 'Ok') { + var converted = _v3.a; + return $elm$core$Result$Ok(converted); + } else { + var problem = _v3.a; + return error(problem); + } + } else { + return error( + $BrianHicks$elm_csv$Csv$Decode$ColumnNotFound(colNum)); + } + case 'Field_': + var name = location.a; + var _v4 = A2($elm$core$Dict$get, name, names); + if (_v4.$ === 'Just') { + var colNum = _v4.a; + var _v5 = $elm$core$List$head( + A2($elm$core$List$drop, colNum, row)); + if (_v5.$ === 'Just') { + var value = _v5.a; + var _v6 = convert(value); + if (_v6.$ === 'Ok') { + var converted = _v6.a; + return $elm$core$Result$Ok(converted); + } else { + var problem = _v6.a; + return error(problem); + } + } else { + return error( + $BrianHicks$elm_csv$Csv$Decode$FieldNotFound(name)); + } + } else { + return $elm$core$Result$Err( + _List_fromArray( + [ + $BrianHicks$elm_csv$Csv$Decode$FieldNotProvided(name) + ])); + } + default: + if (!row.b) { + return error( + $BrianHicks$elm_csv$Csv$Decode$ColumnNotFound(0)); + } else { + if (!row.b.b) { + var only = row.a; + var _v8 = convert(only); + if (_v8.$ === 'Ok') { + var converted = _v8.a; + return $elm$core$Result$Ok(converted); + } else { + var problem = _v8.a; + return error(problem); + } + } else { + return error( + $BrianHicks$elm_csv$Csv$Decode$ExpectedOneColumn( + $elm$core$List$length(row))); + } + } + } + })); +}; +var $BrianHicks$elm_csv$Csv$Decode$string = $BrianHicks$elm_csv$Csv$Decode$fromString($elm$core$Result$Ok); +var $BrianHicks$elm_csv$Csv$Decode$succeed = function (value) { + return $BrianHicks$elm_csv$Csv$Decode$Decoder( + F4( + function (_v0, _v1, _v2, _v3) { + return $elm$core$Result$Ok(value); + })); +}; +var $BrianHicks$elm_csv$Csv$Decode$blank = function (decoder) { + return A2( + $BrianHicks$elm_csv$Csv$Decode$andThen, + function (maybeBlank) { + return $elm$core$String$isEmpty( + $elm$core$String$trim(maybeBlank)) ? $BrianHicks$elm_csv$Csv$Decode$succeed($elm$core$Maybe$Nothing) : A2($BrianHicks$elm_csv$Csv$Decode$map, $elm$core$Maybe$Just, decoder); + }, + $BrianHicks$elm_csv$Csv$Decode$string); +}; +var $BrianHicks$elm_csv$Csv$Decode$Field_ = function (a) { + return {$: 'Field_', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$field = F2( + function (name, _v0) { + var decoder = _v0.a; + return $BrianHicks$elm_csv$Csv$Decode$Decoder( + F3( + function (_v1, fieldNames, row) { + return A3( + decoder, + $BrianHicks$elm_csv$Csv$Decode$Field_(name), + fieldNames, + row); + })); + }); +var $BrianHicks$elm_csv$Csv$Decode$ExpectedFloat = function (a) { + return {$: 'ExpectedFloat', a: a}; +}; var $elm$core$String$toFloat = _String_toFloat; -var $author$project$Main$parseRow = F2( - function (headers, row) { - var values = A2($elm$core$String$split, ',', row); - var lookup = function (key) { - var _v0 = $elm$core$List$head( - A2( - $elm$core$List$filter, - function (_v1) { - var k = _v1.a; - return _Utils_eq(k, key); - }, - A3( - $elm$core$List$map2, - F2( - function (h, v) { - return _Utils_Tuple2(h, v); - }), - headers, - values))); - if (_v0.$ === 'Just') { - var _v2 = _v0.a; - var value = _v2.b; - return value; - } else { - return ''; +var $BrianHicks$elm_csv$Csv$Decode$float = $BrianHicks$elm_csv$Csv$Decode$fromString( + function (value) { + var _v0 = $elm$core$String$toFloat( + $elm$core$String$trim(value)); + if (_v0.$ === 'Just') { + var parsed = _v0.a; + return $elm$core$Result$Ok(parsed); + } else { + return $elm$core$Result$Err( + $BrianHicks$elm_csv$Csv$Decode$ExpectedFloat(value)); + } + }); +var $BrianHicks$elm_csv$Csv$Decode$ExpectedInt = function (a) { + return {$: 'ExpectedInt', a: a}; +}; +var $BrianHicks$elm_csv$Csv$Decode$int = $BrianHicks$elm_csv$Csv$Decode$fromString( + function (value) { + var _v0 = $elm$core$String$toInt( + $elm$core$String$trim(value)); + if (_v0.$ === 'Just') { + var parsed = _v0.a; + return $elm$core$Result$Ok(parsed); + } else { + return $elm$core$Result$Err( + $BrianHicks$elm_csv$Csv$Decode$ExpectedInt(value)); + } + }); +var $BrianHicks$elm_csv$Csv$Decode$into = $BrianHicks$elm_csv$Csv$Decode$succeed; +var $BrianHicks$elm_csv$Csv$Decode$map2 = F3( + function (transform, _v0, _v1) { + var decodeA = _v0.a; + var decodeB = _v1.a; + return $BrianHicks$elm_csv$Csv$Decode$Decoder( + F4( + function (location, fieldNames, rowNum, row) { + var _v2 = _Utils_Tuple2( + A4(decodeA, location, fieldNames, rowNum, row), + A4(decodeB, location, fieldNames, rowNum, row)); + if (_v2.a.$ === 'Ok') { + if (_v2.b.$ === 'Ok') { + var a = _v2.a.a; + var b = _v2.b.a; + return $elm$core$Result$Ok( + A2(transform, a, b)); + } else { + var b = _v2.b.a; + return $elm$core$Result$Err(b); + } + } else { + if (_v2.b.$ === 'Err') { + var a = _v2.a.a; + var b = _v2.b.a; + return $elm$core$Result$Err( + _Utils_ap(a, b)); + } else { + var a = _v2.a.a; + return $elm$core$Result$Err(a); + } + } + })); + }); +var $BrianHicks$elm_csv$Csv$Decode$pipeline = $BrianHicks$elm_csv$Csv$Decode$map2( + F2( + function (value, fn) { + return fn(value); + })); +var $author$project$Main$toBool = function (str) { + _v0$2: + while (true) { + if (str.$ === 'Just') { + switch (str.a) { + case 'True': + return $elm$core$Maybe$Just(true); + case 'False': + return $elm$core$Maybe$Just(false); + default: + break _v0$2; } - }; - var model = lookup('model'); - var nfc = (lookup('NFC') === 'True') ? true : false; - var price = $elm$core$String$toFloat( - lookup('price')); - var rating = $elm$core$String$toFloat( - lookup('rating')); - var ir_blaster = (lookup('IR_blaster') === 'True') ? true : false; - var id = lookup('index'); - var g5 = (lookup('5G') === 'True') ? true : false; - var brand = lookup('brand'); - return A8($author$project$Main$Smartphone, id, brand, model, price, rating, g5, nfc, ir_blaster); + } else { + break _v0$2; + } + } + return $elm$core$Maybe$Nothing; +}; +var $author$project$Main$toCores = function (str) { + _v0$4: + while (true) { + if (str.$ === 'Just') { + switch (str.a) { + case 'dual core': + return $elm$core$Maybe$Just(2); + case 'quad core': + return $elm$core$Maybe$Just(4); + case 'hexa core': + return $elm$core$Maybe$Just(6); + case 'octa core': + return $elm$core$Maybe$Just(8); + default: + break _v0$4; + } + } else { + break _v0$4; + } + } + return $elm$core$Maybe$Nothing; +}; +var $elm$core$String$replace = F3( + function (before, after, string) { + return A2( + $elm$core$String$join, + after, + A2($elm$core$String$split, before, string)); }); +var $elm$core$Maybe$withDefault = F2( + function (_default, maybe) { + if (maybe.$ === 'Just') { + var value = maybe.a; + return value; + } else { + return _default; + } + }); +var $author$project$Main$toGB = function (str) { + return $elm$core$String$toFloat( + $elm$core$String$trim( + A3( + $elm$core$String$replace, + 'GB inbuilt', + '', + A2($elm$core$Maybe$withDefault, '', str)))); +}; +var $author$project$Main$toGHz = function (str) { + return $elm$core$String$toFloat( + $elm$core$String$trim( + A3( + $elm$core$String$replace, + 'GHz Processor', + '', + A2($elm$core$Maybe$withDefault, '', str)))); +}; +var $author$project$Main$toInche = function (str) { + return $elm$core$String$toFloat( + $elm$core$String$trim( + A3( + $elm$core$String$replace, + 'inches', + '', + A2($elm$core$Maybe$withDefault, '', str)))); +}; +var $author$project$Main$decoder = A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'os', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'card', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'camera', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'refresh_rate', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$int)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'resolution', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'screen_size', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toInche, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'RAM', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'Internal_mem', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toGB, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'fast_charging', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'Battery', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'processor_speed', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toGHz, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'num_cores', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toCores, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'processor_brand', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'processor_name', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'IR_blaster', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toBool, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'NFC', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toBool, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + '5G', + A2( + $BrianHicks$elm_csv$Csv$Decode$map, + $author$project$Main$toBool, + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string))), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'rating', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'price', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'model', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'brand', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + A2( + $BrianHicks$elm_csv$Csv$Decode$pipeline, + A2( + $BrianHicks$elm_csv$Csv$Decode$field, + 'id', + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$string)), + $BrianHicks$elm_csv$Csv$Decode$into($author$project$Main$Smartphone))))))))))))))))))))))); var $author$project$Main$parseCSV = function (csv) { - var _v0 = $elm$core$String$lines(csv); - if (!_v0.b) { - return _List_Nil; - } else { - var headerLine = _v0.a; - var dataLines = _v0.b; - var headers = A2($elm$core$String$split, ',', headerLine); - return A2( - $elm$core$List$map, - $author$project$Main$parseRow(headers), - dataLines); - } + return A3($BrianHicks$elm_csv$Csv$Decode$decodeCsv, $BrianHicks$elm_csv$Csv$Decode$FieldNamesFromFirstRow, $author$project$Main$decoder, csv); }; var $author$project$Main$update = F2( function (msg, model) { @@ -6261,11 +7460,22 @@ var $author$project$Main$update = F2( if (msg.a.$ === 'Ok') { var csvData = msg.a.a; var parsedData = $author$project$Main$parseCSV(csvData); - return _Utils_Tuple2( - _Utils_update( - model, - {csvdata: csvData, data: parsedData, error: $elm$core$Maybe$Nothing}), - $elm$core$Platform$Cmd$none); + if (parsedData.$ === 'Ok') { + var data = parsedData.a; + return _Utils_Tuple2( + _Utils_update( + model, + {csvdata: csvData, data: data, error: $elm$core$Maybe$Nothing}), + $elm$core$Platform$Cmd$none); + } else { + return _Utils_Tuple2( + _Utils_update( + model, + { + error: $elm$core$Maybe$Just('Failed to parse CSV data') + }), + $elm$core$Platform$Cmd$none); + } } else { return _Utils_Tuple2( _Utils_update( @@ -6315,21 +7525,17 @@ var $author$project$Scatterplot$mapToPoint = function (smartphone) { }; }), smartphone.price, - smartphone.rating, - $elm$core$Maybe$Just(smartphone.id)); + smartphone.memory, + smartphone.id); }; var $author$project$Scatterplot$filterSmartphones = function (smartphoneList) { var filteredSmartphones = A2($elm$core$List$filterMap, $author$project$Scatterplot$mapToPoint, smartphoneList); - return A3($author$project$Scatterplot$XyData, 'price', 'rating', filteredSmartphones); + return A3($author$project$Scatterplot$XyData, 'price', 'memory', filteredSmartphones); }; var $elm_community$typed_svg$TypedSvg$Types$AnchorMiddle = {$: 'AnchorMiddle'}; var $elm_community$typed_svg$TypedSvg$Types$Percent = function (a) { return {$: 'Percent', a: a}; }; -var $author$project$Scatterplot$Point = F3( - function (pointName, x, y) { - return {pointName: pointName, x: x, y: y}; - }); var $elm_community$typed_svg$TypedSvg$Types$Px = function (a) { return {$: 'Px', a: a}; }; @@ -6697,15 +7903,6 @@ var $gampleman$elm_visualization$Statistics$extentBy = F2( }); var $gampleman$elm_visualization$Statistics$extent = $gampleman$elm_visualization$Statistics$extentBy($elm$core$Basics$identity); var $author$project$Scatterplot$tickCount = 5; -var $elm$core$Maybe$withDefault = F2( - function (_default, maybe) { - if (maybe.$ === 'Just') { - var value = maybe.a; - return value; - } else { - return _default; - } - }); var $author$project$Scatterplot$wideExtent = function (values) { var tup = A2( $elm$core$Maybe$withDefault, @@ -6906,11 +8103,6 @@ var $gampleman$elm_visualization$Axis$element = F4( A2($elm$core$List$map, drawTick, opts.ticks))); }); }); -var $elm$core$Basics$composeL = F3( - function (g, f, x) { - return g( - f(x)); - }); var $elm$svg$Svg$Attributes$x = _VirtualDom_attribute('x'); var $elm$svg$Svg$Attributes$x1 = _VirtualDom_attribute('x1'); var $elm$svg$Svg$Attributes$x2 = _VirtualDom_attribute('x2'); @@ -7001,7 +8193,6 @@ var $gampleman$elm_visualization$Scale$Continuous$invertTransform = F4( $gampleman$elm_visualization$Interpolation$float), untransform); }); -var $elm$core$Basics$ge = _Utils_ge; var $gampleman$elm_visualization$Scale$Continuous$fixPoint = F3( function (maxIterations, initialInput, fn) { var helper = F2( @@ -7142,10 +8333,6 @@ var $gampleman$elm_visualization$Statistics$tickStep = F3( $elm$core$Basics$sqrt(2)) > -1) ? (step1 * 2) : step1)); return (_Utils_cmp(stop, start) < 0) ? (-step2) : step2; }); -var $elm$core$String$cons = _String_cons; -var $elm$core$String$fromChar = function (_char) { - return A2($elm$core$String$cons, _char, ''); -}; var $elm$core$Bitwise$and = _Bitwise_and; var $elm$core$Bitwise$shiftRightBy = _Bitwise_shiftRightBy; var $elm$core$String$repeatHelp = F3( @@ -7353,10 +8540,6 @@ var $author$project$Scatterplot$scatterplot = function (model) { }, model.data); var xScaleLocal = $author$project$Scatterplot$xScale(xValues); - var kreisbeschriftung = A2( - $elm$core$Maybe$withDefault, - A3($author$project$Scatterplot$Point, 'Nothing', 0, 0), - $elm$core$List$head(model.data)).pointName; var half = function (t) { return (t.b - t.a) / 2; }; @@ -7439,7 +8622,7 @@ var $author$project$Scatterplot$scatterplot = function (model) { ]), _List_fromArray( [ - $elm$html$Html$text('Rating') + $elm$html$Html$text('Memory') ])) ])), A2( diff --git a/src/Main.elm b/src/Main.elm index ab2bafa689ff36dacf0cb7762674963379560615..ba887705a9d9b9babf5c631874919d92206cf1a0 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -1,12 +1,11 @@ module Main exposing (..) import Browser -import Dict exposing (Dict) -import Html exposing (Html, div, li, text, ul) +import Csv.Decode as Decode exposing (Decoder) +import Html exposing (Html, div) import Http -import List exposing (map) +import Result exposing (Result(..)) import Scatterplot exposing (viewScatterplot) -import String exposing (lines, split) @@ -19,17 +18,32 @@ main = -- MODEL +-- ohne ram,display type alias Smartphone = - { id : String - , brand : String - , model : String + { id : Maybe String + , brand : Maybe String + , model : Maybe String , price : Maybe Float , rating : Maybe Float - , g5 : Bool - , nfc : Bool - , ir_blaster : Bool + , g5 : Maybe Bool + , nfc : Maybe Bool + , ir_blaster : Maybe Bool + , processor_name : Maybe String + , processor_brand : Maybe String + , num_cors : Maybe Float + , processor_speed : Maybe Float + , battery : Maybe Float + , fast_charging : Maybe Float + , memory : Maybe Float + , ram : Maybe Float + , screen_size : Maybe Float + , resolution : Maybe String + , refresh_rate : Maybe Int + , camera : Maybe String + , card : Maybe String + , os : Maybe String } @@ -65,7 +79,12 @@ update msg model = parsedData = parseCSV csvData in - ( { model | data = parsedData, error = Nothing, csvdata = csvData }, Cmd.none ) + case parsedData of + Ok data -> + ( { model | data = data, error = Nothing, csvdata = csvData }, Cmd.none ) + + Err _ -> + ( { model | error = Just "Failed to parse CSV data" }, Cmd.none ) DataReceived (Err _) -> ( { model | error = Just "Failed to load data" }, Cmd.none ) @@ -82,17 +101,6 @@ view model = ] - --- viewItem : Smartphone -> Html msg --- viewItem smartphone = --- li [] --- [ text ("ID: " ++ smartphone.id) --- , text (", Price: " ++ String.fromFloat smartphone.price) --- , text (", Rating: " ++ String.fromFloat smartphone.rating) --- ] --- SUBSCRIPTIONS - - subscriptions : Model -> Sub Msg subscriptions _ = Sub.none @@ -114,68 +122,92 @@ fetchData = -- PARSING CSV -parseCSV : String -> List Smartphone +decoder : Decoder Smartphone +decoder = + Decode.into Smartphone + |> Decode.pipeline (Decode.field "id" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "brand" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "model" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "price" (Decode.blank Decode.float)) + |> Decode.pipeline (Decode.field "rating" (Decode.blank Decode.float)) + |> Decode.pipeline (Decode.field "5G" (Decode.blank Decode.string |> Decode.map toBool)) + |> Decode.pipeline (Decode.field "NFC" (Decode.blank Decode.string |> Decode.map toBool)) + |> Decode.pipeline (Decode.field "IR_blaster" (Decode.blank Decode.string |> Decode.map toBool)) + |> Decode.pipeline (Decode.field "processor_name" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "processor_brand" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "num_cores" (Decode.blank Decode.string |> Decode.map toCores)) + |> Decode.pipeline (Decode.field "processor_speed" (Decode.blank Decode.string |> Decode.map toGHz)) + |> Decode.pipeline (Decode.field "Battery" (Decode.blank Decode.float)) + |> Decode.pipeline (Decode.field "fast_charging" (Decode.blank Decode.float)) + |> Decode.pipeline (Decode.field "Internal_mem" (Decode.blank Decode.string |> Decode.map toGB)) + |> Decode.pipeline (Decode.field "RAM" (Decode.blank Decode.float)) + |> Decode.pipeline (Decode.field "screen_size" (Decode.blank Decode.string |> Decode.map toInche)) + |> Decode.pipeline (Decode.field "resolution" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "refresh_rate" (Decode.blank Decode.int)) + |> Decode.pipeline (Decode.field "camera" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "card" (Decode.blank Decode.string)) + |> Decode.pipeline (Decode.field "os" (Decode.blank Decode.string)) + + +parseCSV : String -> Result Decode.Error (List Smartphone) parseCSV csv = - case lines csv of - [] -> - [] + Decode.decodeCsv Decode.FieldNamesFromFirstRow decoder csv - headerLine :: dataLines -> - let - headers = - split "," headerLine - in - List.map (parseRow headers) dataLines +toBool : Maybe String -> Maybe Bool +toBool str = + case str of + Just "True" -> + Just True -parseRow : List String -> String -> Smartphone -parseRow headers row = - let - values = - split "," row + Just "False" -> + Just False - lookup key = - case List.head (List.filter (\( k, _ ) -> k == key) (List.map2 (\h v -> ( h, v )) headers values)) of - Just ( _, value ) -> - value + _ -> + Nothing - Nothing -> - "" - id = - lookup "index" +toCores : Maybe String -> Maybe Float +toCores str = + case str of + Just "dual core" -> + Just 2 - brand = - lookup "brand" + Just "quad core" -> + Just 4 - model = - lookup "model" + Just "hexa core" -> + Just 6 - price = - String.toFloat (lookup "price") + Just "octa core" -> + Just 8 - rating = - String.toFloat (lookup "rating") + _ -> + Nothing - g5 = - if lookup "5G" == "True" then - True - else - False +toGHz : Maybe String -> Maybe Float +toGHz str = + str + |> Maybe.withDefault "" + |> String.replace "GHz Processor" "" + |> String.trim + |> String.toFloat - nfc = - if lookup "NFC" == "True" then - True - else - False +toGB : Maybe String -> Maybe Float +toGB str = + str + |> Maybe.withDefault "" + |> String.replace "GB inbuilt" "" + |> String.trim + |> String.toFloat - ir_blaster = - if lookup "IR_blaster" == "True" then - True - else - False - in - Smartphone id brand model price rating g5 nfc ir_blaster +toInche : Maybe String -> Maybe Float +toInche str = + str + |> Maybe.withDefault "" + |> String.replace "inches" "" + |> String.trim + |> String.toFloat diff --git a/src/Scatterplot.elm b/src/Scatterplot.elm index 12620bfdd0ca2cfe1a1ea8639b810b3c8ff8c22a..e1f854083f79fab2ecc43c35eeb0be492d790a15 100644 --- a/src/Scatterplot.elm +++ b/src/Scatterplot.elm @@ -1,7 +1,5 @@ module Scatterplot exposing (..) --- in Ellie: https://ellie-app.com/qQPVFCsZT3La1 - import Axis exposing (..) import Html exposing (Html) import Scale exposing (ContinuousScale) @@ -20,15 +18,33 @@ type alias Model = } + +-- ohne ram,display + + type alias Smartphone = - { id : String - , brand : String - , model : String + { id : Maybe String + , brand : Maybe String + , model : Maybe String , price : Maybe Float , rating : Maybe Float - , g5 : Bool - , nfc : Bool - , ir_blaster : Bool + , g5 : Maybe Bool + , nfc : Maybe Bool + , ir_blaster : Maybe Bool + , processor_name : Maybe String + , processor_brand : Maybe String + , num_cors : Maybe Float + , processor_speed : Maybe Float + , battery : Maybe Float + , fast_charging : Maybe Float + , memory : Maybe Float + , ram : Maybe Float + , screen_size : Maybe Float + , resolution : Maybe String + , refresh_rate : Maybe Int + , camera : Maybe String + , card : Maybe String + , os : Maybe String } @@ -65,10 +81,9 @@ defaultExtent = scatterplot : XyData -> Svg msg scatterplot model = let - kreisbeschriftung : String - kreisbeschriftung = - (Maybe.withDefault (Point "Nothing" 0 0) (List.head model.data)).pointName - + -- kreisbeschriftung : String + -- kreisbeschriftung = + -- (Maybe.withDefault (Point "Nothing" 0 0) (List.head model.data)).pointName xValues : List Float xValues = List.map .x model.data @@ -114,7 +129,7 @@ scatterplot model = [ yAxis yValues , text_ [ x 0, y (Scale.convert yScaleLocal labelPositions.y - 10), textAnchor AnchorMiddle, fontSize <| Px 14 ] - [ Html.text "Rating" ] + [ Html.text "Memory" ] ] -- datenpunkte zeichnen @@ -197,7 +212,7 @@ filterSmartphones smartphoneList = filteredSmartphones = List.filterMap mapToPoint smartphoneList in - XyData "price" "rating" filteredSmartphones + XyData "price" "memory" filteredSmartphones mapToPoint : Smartphone -> Maybe Point @@ -210,8 +225,8 @@ mapToPoint smartphone = } ) smartphone.price - smartphone.rating - (Just smartphone.id) + smartphone.memory + smartphone.id viewScatterplot : Model -> Html msg @@ -226,17 +241,3 @@ viewScatterplot model = Html.div [] [ scatterplot filteredSmartphoneData ] - - - --- type CarType --- = Small_Sporty_Compact_Large_Sedan --- | Sports_Car --- | SUV --- | Wagon --- | Minivan --- | Pickup --- type WheelDrive --- = All_Wheel_Drive --- | Rear_Wheel_Drive --- | Front_Wheel_Drive