Sarveni/Top-VS-Code-Extensions-Data-Analysis
0
1import fs from 'fs';2import Papa from 'papaparse';3 4const csvData = fs.readFileSync('./data.csv', 'utf8');5 6Papa.parse(csvData, {7 header: true,8 dynamicTyping: true,9 skipEmptyLines: true,10 complete: (results) => {11 const data = results.data;12 13 let validExtensions = [];14 let totalDownloads = 0;15 16 for (const row of data) {17 const dl = row.downloads_count;18 if (typeof dl !== 'number' || isNaN(dl) || dl < 0) {19 continue;20 }21 validExtensions.push(dl);22 totalDownloads += dl;23 }24 25 validExtensions.sort((a, b) => b - a);26 const totalExts = validExtensions.length;27 28 function getShare(fraction) {29 const count = Math.max(1, Math.floor(totalExts * fraction));30 let sum = 0;31 for(let i = 0; i < count; i++) sum += validExtensions[i];32 return { count, share: (sum / totalDownloads * 100).toFixed(2) };33 }34 35 function getCountForThreshold(threshold, extArray, totalDl) {36 let running = 0;37 for(let i = 0; i < extArray.length; i++) {38 running += extArray[i];39 if (running >= totalDl * threshold) return i + 1;40 }41 return extArray.length;42 }43 44 const val1_1 = getShare(0.01);45 const val1_5 = getShare(0.05);46 const val1_10 = getShare(0.10);47 48 const val2_50 = getCountForThreshold(0.50, validExtensions, totalDownloads);49 const val3_80 = getCountForThreshold(0.80, validExtensions, totalDownloads);50 51 const stab_05 = getShare(0.005);52 const stab_1 = getShare(0.01);53 const stab_2 = getShare(0.02);54 const stab_5 = getShare(0.05);55 56 // Outlier Test57 const noOutlierExts = validExtensions.slice(1);58 const noOutlierTotalDl = totalDownloads - validExtensions[0];59 const noOutlier_50 = getCountForThreshold(0.50, noOutlierExts, noOutlierTotalDl);60 const noOutlier_80 = getCountForThreshold(0.80, noOutlierExts, noOutlierTotalDl);61 62 const noOutlierTop1Count = Math.max(1, Math.floor(noOutlierExts.length * 0.01));63 let noOutlierTop1Sum = 0;64 for(let i=0; i < noOutlierTop1Count; i++) noOutlierTop1Sum += noOutlierExts[i];65 const noOutlierTop1Share = (noOutlierTop1Sum / noOutlierTotalDl * 100).toFixed(2);66 67 // Option A group calculation68 const top1Count = val1_1.count;69 const top5Count = val1_5.count;70 const top20Count = Math.max(1, Math.floor(totalExts * 0.20));71 72 let top1Sum = 0, next4Sum = 0, next15Sum = 0, bottom80Sum = 0;73 for (let i = 0; i < totalExts; i++) {74 const dl = validExtensions[i];75 if (i < top1Count) top1Sum += dl;76 else if (i < top5Count) next4Sum += dl;77 else if (i < top20Count) next15Sum += dl;78 else bottom80Sum += dl;79 }80 81 console.log(JSON.stringify({82 totalExts,83 totalDownloads,84 validation1: { top1: val1_1, top5: val1_5, top10: val1_10 },85 validation2_50: { count: val2_50, pct: (val2_50/totalExts*100).toFixed(2) },86 validation3_80: { count: val3_80, pct: (val3_80/totalExts*100).toFixed(2) },87 validation4_stability: { p0_5: stab_05, p1: stab_1, p2: stab_2, p5: stab_5 },88 validation5_outlier: {89 removedDl: validExtensions[0],90 new50Count: noOutlier_50,91 new80Count: noOutlier_80,92 newTop1Share: noOutlierTop1Share93 },94 optionA: {95 top1: (top1Sum / totalDownloads * 100).toFixed(2),96 next4: (next4Sum / totalDownloads * 100).toFixed(2),97 next15: (next15Sum / totalDownloads * 100).toFixed(2),98 bottom80: (bottom80Sum / totalDownloads * 100).toFixed(2)99 }100 }, null, 2));101 }102});103 