using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Web; namespace LD_24.Code { /// /// Class used for reading and writing to files /// public static class InOutUtils { /// /// Read lines from a stream /// /// Target filename /// IEnumerable of all the lines private static IEnumerable ReadLines(StreamReader stream) { string line; while ((line = stream.ReadLine()) != null) { yield return line; } } /// /// Read products from a stream reader /// /// Target stream reader /// A list of products public static LinkedList ReadProducts(StreamReader reader) { LinkedList products = new LinkedList(); foreach (string line in ReadLines(reader)) { string[] parts = line.Split(','); string id = parts[0].Trim(); string name = parts[1].Trim(); decimal price = decimal.Parse(parts[2].Trim(), CultureInfo.InvariantCulture); products.Add(new Product(id, name, price)); } return products; } /// /// Read products from a stream /// /// Target stream /// A list of products public static LinkedList ReadProducts(Stream stream) { using (StreamReader reader = new StreamReader(stream)) { return ReadProducts(reader); } } /// /// Read products from a file /// /// Target file /// A list of products public static LinkedList ReadProducts(string filename) { using (StreamReader reader = File.OpenText(filename)) { return ReadProducts(reader); } } /// /// Read orders from a file /// /// Target file /// A list of orders public static LinkedList ReadOrders(string filename) { using (StreamReader reader = File.OpenText(filename)) { return ReadOrders(reader); } } /// /// Read orders from a stream /// /// Target stream /// A list of orders public static LinkedList ReadOrders(Stream stream) { using (StreamReader reader = new StreamReader(stream)) { return ReadOrders(reader); } } /// /// Read orders from a stream reader /// /// Target stream reader /// A list of orders public static LinkedList ReadOrders(StreamReader reader) { LinkedList orders = new LinkedList(); foreach (string line in ReadLines(reader)) { string[] parts = line.Split(','); string customerSurname = parts[0].Trim(); string customerName = parts[1].Trim(); string productID = parts[2].Trim(); int productAmount = int.Parse(parts[3].Trim()); orders.Add(new Order(customerSurname, customerName, productID, productAmount)); } return orders; } /// /// Print a single table row to file /// /// Target file /// Cell data /// Cell widths private static void PrintTableRow(StreamWriter writer, LinkedList cells, LinkedList widths) { foreach (var tuple in cells.Zip(widths, (a, b) => Tuple.Create(a, b))) { if (tuple.Item1[0] == '-') writer.Write("| {0} ", tuple.Item1.Substring(1).PadRight(tuple.Item2)); else writer.Write("| {0} ", tuple.Item1.PadLeft(tuple.Item2)); } writer.WriteLine("|"); } private static LinkedList FindTableWidths(LinkedList> rows, string header, string[] columns) { var allWidths = new Dictionary>(); int o = 0; foreach (var column in columns) { allWidths.Add(o, new LinkedList { column.Length }); o++; } foreach (var row in rows) { int p = 0; foreach (var cell in row) { allWidths[p].Add(cell.Length); p++; } } var widths = new LinkedList(); int totalWidth = 3 * (columns.Length - 1); foreach (var columnWidths in allWidths.Values) { int width = columnWidths.Max(); totalWidth += width; widths.Add(width); } // If the header is longer than the body, make the last column wider. // So the table is a nice rectangle when output to the file if (header.Length > totalWidth) { // Make the last column a bit wider so everything lines up widths.Add(widths.RemoveLast() + header.Length - totalWidth); } return widths; } /// /// Print a table to a file /// /// Target file /// Header above table /// Target list /// Column names /// A IEnumerable for inserting values for each row private static IEnumerable>> PrintTable(StreamWriter writer, string header, IEnumerable list, params string[] columns) { // 1. Collect all the rows LinkedList> rows = new LinkedList>(); foreach (T item in list) { var row = new LinkedList(); yield return Tuple.Create(item, row); rows.Add(row); } // 2. Determine the width of each column var widths = FindTableWidths(rows, header, columns); int totalWidth = 3 * (columns.Length - 1) + 2 * 2 + widths.Sum(); // 3. Display the table writer.WriteLine(new string('-', totalWidth)); writer.WriteLine("| {0} |", header.PadRight(totalWidth - 4)); writer.WriteLine(new string('-', totalWidth)); PrintTableRow(writer, new LinkedList(columns), widths); writer.WriteLine(new string('-', totalWidth)); if (!rows.IsEmpty()) { foreach (var row in rows) { PrintTableRow(writer, row, widths); } } else { writer.WriteLine("| {0} |", "Nėra".PadRight(totalWidth - 4)); } writer.WriteLine(new string('-', totalWidth)); writer.WriteLine(); } /// /// Print orders table to file /// /// Target file /// List of orders /// Header above table public static void PrintOrders(StreamWriter writer, IEnumerable orders, string header) { foreach (var tuple in PrintTable(writer, header, orders, "Pavardė", "Vardas", "-Įtaisas", "-Įtaiso kiekis")) { Order order = tuple.Item1; var row = tuple.Item2; row.Add(order.CustomerSurname); row.Add(order.CustomerName); row.Add(order.ProductID); row.Add(order.ProductAmount.ToString()); } } /// /// Print orders with prices table to file /// /// Target file /// List of orders /// List of products /// Header above table public static void PrintOrdersWithPrices(StreamWriter writer, IEnumerable orders, IEnumerable products, string header) { foreach (var tuple in PrintTable(writer, header, orders, "Pavardė", "Vardas", "-Įtaiso kiekis, vnt.", "-Kaina, eur.")) { Order order = tuple.Item1; var row = tuple.Item2; Product product = TaskUtils.FindByID(products, order.ProductID); row.Add(order.CustomerSurname); row.Add(order.CustomerName); row.Add(order.ProductAmount.ToString()); row.Add(string.Format("{0:f2}", order.ProductAmount * product.Price)); } } /// /// Print a products table to file /// /// Target file /// List of products /// Header above table public static void PrintProducts(StreamWriter writer, IEnumerable products, string header) { foreach (var tuple in PrintTable(writer, header, products, "ID", "Vardas", "-Kaina")) { Product product = tuple.Item1; var row = tuple.Item2; row.Add(product.ID); row.Add(product.Name); row.Add(string.Format("{0:f2}", product.Price)); } } /// /// Print a table of most popular products to file /// /// Target file /// List of orders /// List of most popular products /// Header above table public static void PrintMostPopularProducts(StreamWriter writer, IEnumerable orders, IEnumerable popularProducts, string header) { foreach (var tuple in PrintTable(writer, header, popularProducts, "ID", "Vardas", "-Įtaisų kiekis, vnt.", "-Įtaisų kaina, eur.")) { Product product = tuple.Item1; var row = tuple.Item2; int sales = TaskUtils.CountProductSales(orders, product.ID); row.Add(product.ID); row.Add(product.Name); row.Add(sales.ToString()); row.Add(string.Format("{0:f2}", sales * product.Price)); } } } }