How would you write a c# program analzyzing Crime data? (Constraints below) Desc
ID: 3916961 • Letter: H
Question
How would you write a c# program analzyzing Crime data? (Constraints below)
Description: Create a C#/.NET console application that analyzes crime data based on a comma-separated-value (CSV) file and generates a report that answers a set of provided questions that is saved in a text file. The path to the CSV file and the path to the report text file are provided to the program as command line arguments. If the user runs the program without supplying the arguments, they should be provided with the syntax for running the program.
Questions Constraints
The questions to be answered by the application that are to be used as the basis of a report that the application generates are the following.
What is the range of years included in the data?
How many years of data are included?
What years is the number of murders per year less than 15000?
What are the years and associated robberies per year for years where the number of robberies is greater than 500000?
What is the violent crime per capita rate for 2010? Per capita rate is the number of violent crimes in a year divided by the size of the population that year.
What is the average number of murders per year across all years?
What is the average number of murders per year for 1994 to 1997?
What is the average number of murders per year for 2010 to 2013?
What is the minimum number of thefts per year for 1999 to 2004?
What is the maximum number of thefts per year for 1999 to 2004?
What year had the highest number of motor vehicle thefts?
Example Output (Report)
Crime Analyzer Report
Period: 1994-2013 (20 years)
Years murders per year < 15000: 2010, 2011, 2012, 2013
Robberies per year > 500000: 1994 = 618949, 1995 = 580509, 1996 = 535594
Violent crime per capita rate (2010): 0.0040450234834638
Average murder per year (all years): 16864.25
Average murder per year (1994-1997): 20696.25
Average murder per year (2010-2014): 14608.75
Minimum thefts per year (1999-2004): 6937089
Maximum thefts per year (1999-2004): 7092267
Year of highest number of motor vehicle thefts: 1994
Explanation / Answer
// Create a console application
// Add 2 classes : Crimes.cs & CrimeData.cs
// Keep CrimeData.csv file in <ProjectLocation>indebug folder for debug mode
// Adding CrimeData.csv file content ,which I have used, in the end
// Find code in bold
// Program.cs
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Crimes crimes = new Crimes(args);
}
}
}
// Crimes.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
public class Crimes
{
private static List<CrimeData> CrimeDataList = new List<CrimeData>();
public Crimes(string[] args)
{
string csvFilePath = string.Empty;
string reportFilePath = string.Empty;
string startupPath = Directory.GetCurrentDirectory();
// Debug Mode
if (Debugger.IsAttached)
{
csvFilePath = Path.Combine(startupPath, "CrimeData.csv");
reportFilePath = Path.Combine(startupPath, "CrimeReport.txt");
}
// Release Mode
else
{
if (args.Length != 2)
{
Console.WriteLine("Invalid call. Valid call example : CrimeAnalyzer <crime_csv_file_path> <report_file_path>");
Console.ReadLine();
return;
}
else
{
csvFilePath = args[0];
reportFilePath = args[1];
if (!csvFilePath.Contains("\"))
{
csvFilePath = Path.Combine(startupPath, csvFilePath);
}
if (!reportFilePath.Contains("\"))
{
reportFilePath = Path.Combine(startupPath, reportFilePath);
}
}
}
if (File.Exists(csvFilePath))
{
if (ReadData(csvFilePath))
{
try
{
var file = File.Create(reportFilePath);
file.Close();
}
catch (Exception fe)
{
Console.WriteLine($"Unable to create report file at : {reportFilePath}");
}
WriteReport(reportFilePath);
}
}
else
{
Console.Write($"Crime data file does not exist at path: {csvFilePath}");
}
Console.ReadLine();
}
private static bool ReadData(string filePath)
{
Console.WriteLine($"Reading data from file : {filePath}");
try
{
int columns = 0;
string[] crimeDataLines = File.ReadAllLines(filePath);
for (int index = 0; index < crimeDataLines.Length; index++)
{
string crimeDataLine = crimeDataLines[index];
string[] data = crimeDataLine.Split(',');
if (index == 0) // Header
{
columns = data.Length;
}
else
{
if (columns != data.Length)
{
Console.WriteLine($"Row {index} contains {data.Length} values. It should contain {columns}.");
return false;
}
else
{
try
{
CrimeData crimeData = new CrimeData();
crimeData.Year = Convert.ToInt32(data[0]);
crimeData.Population = Convert.ToInt32(data[1]);
crimeData.Murders = Convert.ToInt32(data[2]);
crimeData.Rapes = Convert.ToInt32(data[3]);
crimeData.Robberies = Convert.ToInt32(data[4]);
crimeData.ViolentCrimes = Convert.ToInt32(data[5]);
crimeData.Thefts = Convert.ToInt32(data[6]);
crimeData.MotorVehicleThefts = Convert.ToInt32(data[7]);
CrimeDataList.Add(crimeData);
}
catch (InvalidCastException e)
{
Console.WriteLine($"Row {index} contains invalid value.");
return false;
}
}
}
}
Console.WriteLine($"Data read completed successfully.");
return true;
}
catch (Exception ex)
{
Console.WriteLine("Error in reading data from csv file.");
throw ex;
}
}
private static void WriteReport(string filePath)
{
try
{
if (CrimeDataList != null && CrimeDataList.Any())
{
Console.WriteLine($"Calculating the desired data and writing it to report file : {filePath}");
StringBuilder sb = new StringBuilder();
sb.Append("Crime Analyzer Report");
sb.Append(Environment.NewLine);
// 1
// Period
int minYear = CrimeDataList.Min(x => x.Year);
int maxYear = CrimeDataList.Max(x => x.Year);
// Years
int years = maxYear - minYear + 1;
sb.Append($"Period: {minYear}-{maxYear} ({years} years)");
sb.Append(Environment.NewLine);
// 2
var mYears = from crimeData in CrimeDataList
where crimeData.Murders < 15000
select crimeData.Year;
string mYearsStr = string.Empty;
for (int i = 0; i < mYears.Count(); i++)
{
mYearsStr += mYears.ElementAt(i).ToString();
// No comma after last value
if (i < mYears.Count() - 1) mYearsStr += ", ";
}
sb.Append($"Years murders per year < 15000: {mYearsStr}");
sb.Append(Environment.NewLine);
// 3
var rYears = from crimeData in CrimeDataList
where crimeData.Robberies > 500000
select crimeData;
string rYearsStr = string.Empty;
for (int i = 0; i < rYears.Count(); i++)
{
CrimeData crimeData = rYears.ElementAt(i);
rYearsStr += $"{crimeData.Year} = {crimeData.Robberies}";
// No comma after last value
if (i < rYears.Count() - 1) rYearsStr += ", ";
}
sb.Append($"Robberies per year > 500000: {rYearsStr}");
sb.Append(Environment.NewLine);
// 4
var vCrime = from crimeData in CrimeDataList
where crimeData.Year == 2010
select crimeData;
CrimeData vCrimeData = vCrime.First();
double vCrimePerCapita = (double)vCrimeData.ViolentCrimes / (double)vCrimeData.Population;
sb.Append($"Violent crime per capita rate (2010): {vCrimePerCapita}");
sb.Append(Environment.NewLine);
// 5
double avgMurders = CrimeDataList.Sum(x => x.Murders) / CrimeDataList.Count;
sb.Append($"Average murder per year (all years): {avgMurders}");
sb.Append(Environment.NewLine);
// 6
int murders1 = CrimeDataList
.Where(x => x.Year >= 1994 && x.Year <= 1997)
.Sum(y => y.Murders);
double avgMurders1 = murders1 / CrimeDataList.Count;
sb.Append($"Average murder per year (1994-1997): {avgMurders1}");
sb.Append(Environment.NewLine);
// 7
int murders2 = CrimeDataList
.Where(x => x.Year >= 2010 && x.Year <= 2014)
.Sum(y => y.Murders);
double avgMurders2 = murders2 / CrimeDataList.Count;
sb.Append($"Average murder per year (2010-2014): {avgMurders2}");
sb.Append(Environment.NewLine);
// 8
int minTheft = CrimeDataList
.Where(x => x.Year >= 1999 && x.Year <= 2004)
.Min(x => x.Thefts);
sb.Append($"Minimum thefts per year (1999-2004): {minTheft}");
sb.Append(Environment.NewLine);
// 9
int maxTheft = CrimeDataList
.Where(x => x.Year >= 1999 && x.Year <= 2004)
.Max(x => x.Thefts);
sb.Append($"Maximum thefts per year (1999-2004): {maxTheft}");
sb.Append(Environment.NewLine);
// 10
int yMaxVehicleTheft = CrimeDataList.OrderByDescending(x => x.MotorVehicleThefts).First().Year;
sb.Append($"Year of highest number of motor vehicle thefts: {yMaxVehicleTheft}");
sb.Append(Environment.NewLine);
using (var stream = new StreamWriter(filePath))
{
stream.Write(sb.ToString());
}
Console.WriteLine();
Console.WriteLine(sb.ToString());
Console.WriteLine();
Console.WriteLine($"Written report file successfully at : {filePath}");
}
else
{
Console.WriteLine($"No data to write.");
}
}
catch (Exception ex)
{
Console.WriteLine("Error in writing report file.");
throw ex;
}
}
}
}
// CrimeData.cs
namespace ConsoleApp
{
public class CrimeData
{
public int Year { get; set; }
public int Population { get; set; }
public int Murders { get; set; }
public int Rapes { get; set; }
public int Robberies { get; set; }
public int ViolentCrimes { get; set; }
public int Thefts { get; set; }
public int MotorVehicleThefts { get; set; }
}
}
// CrimeData.csv
Year,Population,Murders,Rapes,Robberies,ViolentCrimes,Thefts,MotorVehicleThefts
1990,123456,123,321,356,984,7569,1230
1991,234567,7857,321,356,984,7569,1230
1992,345678,123,321,356,984,356,1230
1993,456789,456,9876,356,984,7569,1230
1994,567890,245,321,356,984,7569,1230
1995,678900,9877,321,356,984,7569,356
1996,789000,11111,9876,356,984,7569,1230
1997,890000,3245,321,356,984,7569,1230
1998,900000,123,321,9876,984,7569,1230
1999,1234567,123,321,356,984,356,1230
2000,2345678,12345,321,356,984,7569,1230
2001,3456789,123,984,356,984,7569,1230
2002,4567890,123,321,356,984,7569,356
2003,5678900,123,321,984,9876,7569,1230
2004,6789000,12345,321,356,984,7569,1230
2005,7890000,123,984,356,984,356,1230
2006,8900000,9876,321,356,984,7569,1230
2007,9000000,123,321,356,984,7569,1230
2008,12345678,123,321,984,984,7569,356
2009,23456789,12345,321,356,984,7569,1230
2010,34567890,123,984,356,345678,7569,1230
2011,45678900,123,321,356,984,356,1230
2012,56789000,12345,984,356,984,7569,1230
2013,67890000,123,321,356,984,7569,1230
2014,78900000,9876,321,984,984,7569,356
2015,89000000,123,321,356,984,356,1230
2016,90000000,123,321,356,984,7569,1230
2017,100000000,9876,321,356,984,356,1230
2018,1200000000,123,321,356,984,7569,1230
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.