diff --git a/Lab5/Lab5.TouristInformationCenter/InOutUtils.cs b/Lab5/Lab5.TouristInformationCenter/InOutUtils.cs new file mode 100644 index 0000000..d61e25e --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/InOutUtils.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.IO.Compression; + +namespace Lab5.TouristInformationCenter +{ + /// + /// Class that stores functions that are related to reading and writing data + /// + class InOutUtils + { + /// + /// Append the museums from the second container to the first one + /// + /// First container + /// Second container + private static void AppendContainer(MuseumsContainer container1, MuseumsContainer container2) + { + for (int i = 0; i < container2.Count; i++) + { + container1.Add(container2.Get(i)); + } + } + + /// + /// Decode a list of museums from a given list of lines. + /// + /// + /// Container of museums + public static MuseumsContainer DecodeMuseums(List lines) + { + MuseumsContainer container = new MuseumsContainer(lines.Count-2); + string city = lines[0]; + string manager = lines[1]; + for (int i = 2; i < lines.Count; i++) + { + string line = lines[i]; + string[] values = line.Split(';'); + string name = values[0]; + string type = values[1]; + List workdays = new List(); + for (int j = 1; j <= 7; j++) + { + if (int.Parse(values[j + 1]) == 1) + { + workdays.Add((Weekday)j); + } + } + double price = double.Parse(values[9]); + bool hasGuide = int.Parse(values[10]) == 1; + + Museum museum = new Museum(name, city, manager, type, workdays, price, hasGuide); + container.Add(museum); + } + return container; + } + + /// + /// Read and decode a list of museums from a file. + /// + /// Target file + /// Container of museums + public static MuseumsContainer ReadMuseumsFromCSV(string filename) + { + List lines = new List(); + foreach (string line in File.ReadAllLines(filename, Encoding.UTF8)) + { + lines.Add(line); + } + return DecodeMuseums(lines); + } + + /// + /// Read all the entries from a zip file and decode the museums inside the csv entries. + /// + /// Target filename + /// Register of museums + public static MuseumsContainer ReadMuseumsFromZIP(string filename) + { + MuseumsContainer mainContainer = new MuseumsContainer(); + + using (ZipArchive zipFile = ZipFile.Open(filename, ZipArchiveMode.Read)) + { + foreach (ZipArchiveEntry entry in zipFile.Entries) + { + if (!entry.Name.EndsWith(".csv")) continue; + List lines = new List(); + using (StreamReader reader = new StreamReader(entry.Open(), Encoding.UTF8)) + { + while (!reader.EndOfStream) + { + lines.Add(reader.ReadLine()); + } + } + + MuseumsContainer contaienr = DecodeMuseums(lines); + AppendContainer(mainContainer, contaienr); + } + + } + + return mainContainer; + } + + /// + /// Read and decode lists of museums from multiple files and put into a single register. + /// + /// Target files + /// Register containing museums from all files + public static MuseumsContainer ReadMuseums(params string[] filenames) + { + MuseumsContainer mainContainer = new MuseumsContainer(); + foreach (string filename in filenames) + { + if (filename.EndsWith(".csv")) + { + AppendContainer(mainContainer, ReadMuseumsFromCSV(filename)); + } + else if(filename.EndsWith(".zip")) + { + AppendContainer(mainContainer, ReadMuseumsFromZIP(filename)); + } + } + return mainContainer; + } + + private static string CreateMuseumLine(Museum museum) + { + string workDays = ""; + workDays += museum.Workdays.Contains(Weekday.Monday) ? "1" : "0"; + workDays += museum.Workdays.Contains(Weekday.Tuesday) ? ";1" : ";0"; + workDays += museum.Workdays.Contains(Weekday.Wednesday) ? ";1" : ";0"; + workDays += museum.Workdays.Contains(Weekday.Thursday) ? ";1" : ";0"; + workDays += museum.Workdays.Contains(Weekday.Friday) ? ";1" : ";0"; + workDays += museum.Workdays.Contains(Weekday.Saturday) ? ";1" : ";0"; + workDays += museum.Workdays.Contains(Weekday.Sunday) ? ";1" : ";0"; + + return String.Join(";", museum.City, museum.Name, workDays, museum.Price); + } + + /// + /// Write and encode a list of museums to a file. The file will be in a csv format using ";" as seperators. + /// + /// Target file + /// Container of museums + public static void WriteMuseums(string filename, MuseumsContainer container) + { + string[] lines = new string[container.Count]; + for (int i = 0; i < container.Count; i++) + { + Museum museum = container.Get(i); + lines[i] = CreateMuseumLine(museum); + } + File.WriteAllLines(filename, lines, Encoding.UTF8); + } + + /// + /// Write and encode a list of museums to a file from a register. + /// + /// Target location + /// Register containing museums + public static void WriteMuseums(string filename, MuseumsRegister register) + { + int n = register.Count(); + string[] lines = new string[n]; + for (int i = 0; i < n; i++) + { + Museum museum = register.GetByIndex(i); + lines[i] = CreateMuseumLine(museum); + } + File.WriteAllLines(filename, lines, Encoding.UTF8); + } + + /// + /// Write out a container of museums in a table to the console. + /// + /// Container of museums + public static void PrintMuseums(MuseumsContainer container) + { + if (container.Count == 0) + { + Console.WriteLine("Nėra"); + return; + } + + Console.WriteLine(new string('-', 123)); + Console.WriteLine("| {0,-20} | {1,-10} | {2,-20} | {3,-10} | {4,18} | {5,13} | {6,-4} |", "Vardas", "Miestas", "Atsakingas", "Tipas", "Darbo dienų kiekis", "Kaina", "Turi gidą?"); + Console.WriteLine(new string('-', 123)); + for (int i = 0; i < container.Count; i++) + { + Museum m = container.Get(i); + Console.WriteLine("| {0,-20} | {1,-10} | {2,-20} | {3,-10} | {4,18} | {5,13:f2} | {6,-10} |", m.Name, m.City, m.Manager, m.Type, m.Workdays.Count, m.Price, m.HasGuide ? "Taip" : "Ne"); + } + Console.WriteLine(new string('-', 123)); + } + + /// + /// Write out a list of museums in a table to the console from a register. + /// + /// Register containing museums + public static void PrintMuseums(MuseumsRegister register) + { + MuseumsContainer museums = new MuseumsContainer(); + for (int i = 0; i < register.Count(); i++) + { + museums.Add(register.GetByIndex(i)); + } + PrintMuseums(museums); + } + } +} diff --git a/Lab5/Lab5.TouristInformationCenter/Lab5.TouristInformationCenter.csproj b/Lab5/Lab5.TouristInformationCenter/Lab5.TouristInformationCenter.csproj new file mode 100644 index 0000000..23df604 --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/Lab5.TouristInformationCenter.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp2.1 + + + diff --git a/Lab5/Lab5.TouristInformationCenter/Museum.cs b/Lab5/Lab5.TouristInformationCenter/Museum.cs new file mode 100644 index 0000000..09cbfa4 --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/Museum.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Lab5.TouristInformationCenter +{ + /// + /// Class used for storing data related a single museum. + /// + class Museum + { + public string Name { get; set; } + public string City { get; set; } + public string Manager { get; set; } + public string Type { get; set; } + public List Workdays { get; set; } + public double Price { get; set; } + public bool HasGuide { get; set; } + public Museum(string name, string city, string manager, string type, List workdays, double price, bool hasGuide) + { + Name = name; + Manager = manager; + City = city; + Type = type; + Workdays = workdays; + Price = price; + HasGuide = hasGuide; + } + } +} diff --git a/Lab5/Lab5.TouristInformationCenter/MuseumsContainer.cs b/Lab5/Lab5.TouristInformationCenter/MuseumsContainer.cs new file mode 100644 index 0000000..be47016 --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/MuseumsContainer.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Lab5.TouristInformationCenter +{ + class MuseumsContainer + { + private Museum[] museums; + private int Capacity; + public int Count { get; private set; } + public MuseumsContainer(int capacity = 16) + { + Capacity = capacity; + museums = new Museum[capacity]; + } + + public MuseumsContainer(MuseumsContainer container) : this(container.Capacity) + { + for (int i = 0; i < container.Count; i++) + { + Add(container.Get(i)); + } + } + + /// + /// Add a museum to the end of the container + /// + /// Target museum + public void Add(Museum museum) + { + if (Count == Capacity) + { + EnsureCapacity(Capacity * 2); + } + + museums[Count] = museum; + Count++; + } + + /// + /// Get a musem by index from container + /// + /// Target index + /// Museum at given index + public Museum Get(int index) + { + return museums[index]; + } + + /// + /// Check if given museum exists in container + /// + /// Target museum + /// True if contains + public bool Contains(Museum museum) + { + for (int i = 0; i < Count; i++) + { + if (museums[i].Equals(museum)) + { + return true; + } + } + return false; + } + + /// + /// Put a museum at a specific index + /// + /// Target index + /// Target museum + public void Put(int index, Museum museum) + { + museums[index] = museum; + } + + /// + /// Filter by property "HasGuide" + /// + /// Target value + /// A filtered container of museums + public MuseumsContainer FilterByGuide(bool hasGuide) + { + MuseumsContainer filtered = new MuseumsContainer(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (museum.HasGuide == hasGuide) + { + filtered.Add(museum); + } + } + return filtered; + } + + /// + /// Filter by property "Type". + /// + /// Target type + /// A filtered container of museums + public MuseumsContainer FilterByType(string type) + { + MuseumsContainer filtered = new MuseumsContainer(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (museum.Type == type) + { + filtered.Add(museum); + } + } + return filtered; + } + + /// + /// Filter by property "Price". + /// + /// Maximum allowed price to be included + /// A container with museums that dont't have a larger price then "maxPrice" + public MuseumsContainer FilterByPrice(double maxPrice) + { + MuseumsContainer filtered = new MuseumsContainer(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (museum.Price <= maxPrice) + { + filtered.Add(museum); + } + } + return filtered; + } + + /// + /// Filter by property "Type" + /// + /// Target city + /// A container of museums + public MuseumsContainer FilterByCity(string city) + { + MuseumsContainer filtered = new MuseumsContainer(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (museum.City == city) + { + filtered.Add(museum); + } + } + return filtered; + } + + /// + /// Return a list of "active" museums from the contaner. + /// A museum is considered active if it is working at least some amount a week. + /// + /// Threshold which determines what is active + /// A container of "active" museums + public MuseumsContainer FilterByActivity(int threshold) + { + MuseumsContainer filtered = new MuseumsContainer(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (museum.Workdays.Count >= threshold) + { + filtered.Add(museum); + } + } + return filtered; + } + + /// + /// Filter by property "Name" + /// + /// Target name + /// A filtered container + public MuseumsContainer FilterByName(string name) + { + MuseumsContainer filtered = new MuseumsContainer(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (museum.Name == name) + { + filtered.Add(museum); + } + } + return filtered; + } + + /// + /// Get all of the different types of cities. + /// + /// A list of city names + public List GetAllCities() + { + List cities = new List(); + for (int i = 0; i < Count; i++) + { + Museum museum = museums[i]; + if (!cities.Contains(museum.City)) + { + cities.Add(museum.City); + } + } + return cities; + } + + /// + /// Sort container by "City" and "Name" in alphabetical order. + /// + public void Sort() + { + for (int i = 0; i < Count - 1; i++) + { + for (int j = i + 1; j < Count; j++) + { + Museum a = museums[i]; + Museum b = museums[j]; + int nameCompare = a.Name.CompareTo(b.Name); + int cityCompare = a.City.CompareTo(b.City); + if (cityCompare > 0 || (cityCompare == 0 && nameCompare > 0)) + { + museums[i] = b; + museums[j] = a; + } + } + } + } + + private void EnsureCapacity(int minimumCapacity) + { + if (minimumCapacity <= Capacity) return; + + Museum[] museumsClone = new Museum[minimumCapacity]; + for (int i = 0; i < Count; i++) + { + museumsClone[i] = museums[i]; + } + Capacity = minimumCapacity; + museums = museumsClone; + } + } +} diff --git a/Lab5/Lab5.TouristInformationCenter/MuseumsKaunas.csv b/Lab5/Lab5.TouristInformationCenter/MuseumsKaunas.csv new file mode 100644 index 0000000..f3076a3 --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/MuseumsKaunas.csv @@ -0,0 +1,8 @@ +Kaunas +Jonas Jonaitis +KaunoMuziejus1;Dailė;1;0;0;0;1;0;1;3,40;0 +KaunoMuziejusB;Computer;1;1;0;1;1;1;1;14,39;1 +KaunoMuziejus3;History;0;1;0;0;1;0;0;3,26;0 +KaunoMuziejus4;Dailė;0;1;0;1;1;0;1;9,47;1 +KaunoMuziejus5;Space;1;1;0;0;0;0;1;1,99;1 +KaunoMuziejusB;Space;1;1;1;1;0;1;1;0,99;1 \ No newline at end of file diff --git a/Lab5/Lab5.TouristInformationCenter/MuseumsRegister.cs b/Lab5/Lab5.TouristInformationCenter/MuseumsRegister.cs new file mode 100644 index 0000000..f538573 --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/MuseumsRegister.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Lab5.TouristInformationCenter +{ + /// + /// Class used to store multiple museums in one place + /// + class MuseumsRegister + { + private MuseumsContainer AllMuseums; + + public MuseumsRegister() + { + AllMuseums = new MuseumsContainer(); + } + + public MuseumsRegister(MuseumsContainer museums) + { + AllMuseums = new MuseumsContainer(museums); + } + + /// + /// Add one museum to the register. + /// + /// Target museum + public void Add(Museum museum) + { + AllMuseums.Add(museum); + } + + /// + /// The amount of stored museums in the register. + /// + /// Museum count + public int Count() + { + return AllMuseums.Count; + } + + /// + /// Access museum from register by index + /// + /// Target index + /// Museum + public Museum GetByIndex(int index) + { + return AllMuseums.Get(index); + } + + /// + /// Return a list of active museums from the register. + /// A museum is considered active if it is working at least some amount a week. + /// + /// Threshold which determines what is active + /// A list of active museums + public MuseumsContainer FilterByActiveMuseums(int threshold) + { + return AllMuseums.FilterByActivity(threshold); + } + + /// + /// Find museum that work the most days in a week + /// + /// Most active museum + public Museum FindMostActiveMuseum() + { + if (AllMuseums.Count == 0) + { + return null; + } + + Museum mostActive = AllMuseums.Get(0); + for (int i = 0; i < AllMuseums.Count; i++) + { + Museum museum = AllMuseums.Get(i); + if (museum.Workdays.Count > mostActive.Workdays.Count) + { + mostActive = museum; + } + } + return mostActive; + } + + /// + /// Find all museums that work the most days in a week + /// + /// + public MuseumsContainer FindMostActiveMuseums() + { + Museum mostActive = FindMostActiveMuseum(); + MuseumsContainer activeMuseums = new MuseumsContainer(); + for (int i = 0; i < AllMuseums.Count; i++) + { + Museum museum = AllMuseums.Get(i); + if (museum.Workdays.Count == mostActive.Workdays.Count) + { + activeMuseums.Add(museum); + } + } + return activeMuseums; + } + + /// + /// Get all of the different types of cities. + /// + /// A list of city names + public List GetAllCities() + { + return AllMuseums.GetAllCities(); + } + + /// + /// Filter the museums by city name from register + /// + /// Target city + /// A container of museums + public MuseumsContainer FilterByCity(string city) + { + return AllMuseums.FilterByCity(city); + } + + /// + /// Filter by property "Type". + /// + /// Target type + /// A filtered container of museums + public MuseumsContainer FilterByType(string type) + { + return AllMuseums.FilterByType(type); + } + + private List GetMuseumNames() + { + List result = new List(); + for (int i = 0; i < AllMuseums.Count; i++) + { + Museum museum = AllMuseums.Get(i); + if (!result.Contains(museum.Name)) + { + result.Add(museum.Name); + } + } + return result; + } + + /// + /// Find all museums that have matching names + /// + /// A container with museums that have matching names + public MuseumsContainer FindMuseumsWithDuplicateNames() + { + MuseumsContainer result = new MuseumsContainer(); + List names = GetMuseumNames(); + foreach (string name in names) + { + MuseumsContainer museumsByName = AllMuseums.FilterByName(name); + if (museumsByName.Count <= 1) continue; + + for (int i = 0; i < museumsByName.Count; i++) + { + result.Add(museumsByName.Get(i)); + } + } + return result; + } + + } +} diff --git a/Lab5/Lab5.TouristInformationCenter/MuseumsVilnius.csv b/Lab5/Lab5.TouristInformationCenter/MuseumsVilnius.csv new file mode 100644 index 0000000..7cb90da --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/MuseumsVilnius.csv @@ -0,0 +1,7 @@ +Vilnius +Petras Petraitis +VilnausMuziejus1;Dailė;1;0;0;1;1;0;0;5,49;0 +VilnausMuziejus2;Computer;1;1;0;1;1;1;1;0,00;1 +VilnausMuziejusA;Dailė;0;1;1;1;1;0;0;1,23;0 +VilnausMuziejusA;Food;1;1;1;1;1;1;0;6,90;0 +VilnausMuziejus5;History;0;1;0;1;1;0;1;10,49;0 \ No newline at end of file diff --git a/Lab5/Lab5.TouristInformationCenter/Program.cs b/Lab5/Lab5.TouristInformationCenter/Program.cs new file mode 100644 index 0000000..c76e95c --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/Program.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace Lab5.TouristInformationCenter +{ + class Program + { + static void Main(string[] args) + { + // Read all museums from initial data files + MuseumsContainer container = InOutUtils.ReadMuseums("MuseumsKaunas.csv", "MuseumsVilnius.csv"); + MuseumsRegister register = new MuseumsRegister(container); + Console.WriteLine("Visi muziejai:"); + InOutUtils.PrintMuseums(register); + Console.WriteLine(); + + // Write out a list of cities and if they have at least one museum that is free and with a guide + List cities = register.GetAllCities(); + foreach (string city in cities) + { + MuseumsContainer freeMuseumsWithGuide = register + .FilterByCity(city) + .FilterByPrice(0) + .FilterByGuide(true); + bool passesCriteria = freeMuseumsWithGuide.Count > 0; + Console.WriteLine("{0}: {1}", city, passesCriteria ? "Taip" : "Ne"); + } + Console.WriteLine(); + + // Find all museums that are the most active + MuseumsContainer mostActiveMuseums = register.FindMostActiveMuseums(); + Console.WriteLine("Aktyviausi muziejai:"); + InOutUtils.PrintMuseums(mostActiveMuseums); + Console.WriteLine(); + + // Find museums that have duplicate names + MuseumsContainer museumsWithDuplicateNames = register.FindMuseumsWithDuplicateNames(); + InOutUtils.WriteMuseums("Sutampta.csv", museumsWithDuplicateNames); + + // Find all art museums and sort them + MuseumsContainer artMuseums = register.FilterByType("Dailė"); + artMuseums.Sort(); + InOutUtils.WriteMuseums("Dailė.csv", artMuseums); + } + } +} diff --git a/Lab5/Lab5.TouristInformationCenter/Weekday.cs b/Lab5/Lab5.TouristInformationCenter/Weekday.cs new file mode 100644 index 0000000..6e8e4a0 --- /dev/null +++ b/Lab5/Lab5.TouristInformationCenter/Weekday.cs @@ -0,0 +1,17 @@ + +namespace Lab5.TouristInformationCenter +{ + /// + /// Used for storing weekdays as numbers rather than strings + /// + enum Weekday + { + Monday = 1, + Tuesday = 2, + Wednesday = 3, + Thursday = 4, + Friday = 5, + Saturday = 6, + Sunday = 7 + } +} diff --git a/Lab5/Lab5.sln b/Lab5/Lab5.sln index 3da4e7c..1b95ae3 100644 --- a/Lab5/Lab5.sln +++ b/Lab5/Lab5.sln @@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.1525 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab5.Exercises.Register", "Lab5.Exercises.Register\Lab5.Exercises.Register.csproj", "{47BEC004-9D86-465A-9331-B525D8517FA5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lab5.Exercises.Register", "Lab5.Exercises.Register\Lab5.Exercises.Register.csproj", "{47BEC004-9D86-465A-9331-B525D8517FA5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lab5.Sport", "Lab5.Sport\Lab5.Sport.csproj", "{0644A0A7-0F28-4566-AA58-1DFD1AF25D6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab5.TouristInformationCenter", "Lab5.TouristInformationCenter\Lab5.TouristInformationCenter.csproj", "{29EFA044-DDF8-4674-8060-36CF3661D825}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +19,14 @@ Global {47BEC004-9D86-465A-9331-B525D8517FA5}.Debug|Any CPU.Build.0 = Debug|Any CPU {47BEC004-9D86-465A-9331-B525D8517FA5}.Release|Any CPU.ActiveCfg = Release|Any CPU {47BEC004-9D86-465A-9331-B525D8517FA5}.Release|Any CPU.Build.0 = Release|Any CPU + {0644A0A7-0F28-4566-AA58-1DFD1AF25D6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0644A0A7-0F28-4566-AA58-1DFD1AF25D6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0644A0A7-0F28-4566-AA58-1DFD1AF25D6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0644A0A7-0F28-4566-AA58-1DFD1AF25D6A}.Release|Any CPU.Build.0 = Release|Any CPU + {29EFA044-DDF8-4674-8060-36CF3661D825}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29EFA044-DDF8-4674-8060-36CF3661D825}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29EFA044-DDF8-4674-8060-36CF3661D825}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29EFA044-DDF8-4674-8060-36CF3661D825}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE