diff --git a/examples/CSVFiles/CMakeLists.txt b/examples/csvfiles/CMakeLists.txt similarity index 72% rename from examples/CSVFiles/CMakeLists.txt rename to examples/csvfiles/CMakeLists.txt index 7bb38a4..d811932 100644 --- a/examples/CSVFiles/CMakeLists.txt +++ b/examples/csvfiles/CMakeLists.txt @@ -1,3 +1,3 @@ -add_executable(csvfiles main.cpp) +add_executable(csvfiles csvfiles.cpp) ROSA_add_library_dependencies(csvfiles ROSAConfig) ROSA_add_library_dependencies(csvfiles ROSAApp) diff --git a/examples/CSVFiles/main.cpp b/examples/csvfiles/csvfiles.cpp similarity index 98% rename from examples/CSVFiles/main.cpp rename to examples/csvfiles/csvfiles.cpp index b010a0a..9f0e337 100644 --- a/examples/CSVFiles/main.cpp +++ b/examples/csvfiles/csvfiles.cpp @@ -1,358 +1,358 @@ -//===-- examples/CSVFiles/main.cpp ------------------------------*- C++ -*-===// +//===-- examples/csvfiles/csvfiles.cpp ------------------------------*- C++ -*-===// // // The RoSA Framework // // Distributed under the terms and conditions of the Boost Software License 1.0. // See accompanying file LICENSE. // // If you did not receive a copy of the license file, see // http://www.boost.org/LICENSE_1_0.txt. // //===----------------------------------------------------------------------===// /// -/// \file examples/basic-system/basic-system.cpp +/// \file examples/csvfiles/csvfiles.cpp /// /// \author Edwin Willegger (edwin.willegger@tuwien.ac.at) /// /// \date 2019-2020 /// /// \brief A simple example on the basic \c rosa::csv, \c rosa::iterator and /// \c rosa::writer classes. Focus is on the tuple impementations. /// //===----------------------------------------------------------------------===// #include #include #include #include #include #include #include #include #include #include #include #include // includes for an complete example to read and write // with sensors and agents. #include "rosa/app/Application.hpp" #include "rosa/config/version.h" // includes to test the basic functionality // to read and write tuples. #include "rosa/support/csv/CSVReader.hpp" #include "rosa/support/csv/CSVWriter.hpp" #include "rosa/support/iterator/split_tuple_iterator.hpp" #include "rosa/support/writer/split_tuple_writer.hpp" /// the name of the example const std::string ExampleName = "csvfiles"; /// How many cycles of simulation to perform. const size_t NumberOfSimulationCycles = 10; /// Paths for the CSV files for simulation. /// input csv files const std::string csvPath = "../examples/CSVFiles/"; const std::string csvFileWithHeader = csvPath + "HR-New.csv"; const std::string csvFileNoHeader = csvPath + "HR.csv"; const std::string csvFileHeaderSemi = csvPath + "HR-New-Semicolon.csv"; /// output csv files const std::string csvFileWriteHea = csvPath + "csvwriter_noheader.csv"; const std::string csvFileWriteNoHeaSplit = csvPath + "csvSplitwriter_noheader.csv"; using namespace rosa; /// /// This function tests the basic CSVIterator capablities, and shows you /// how you could work with this class. /// void testtupleCSVReader(void){ //different streams to get the csv data out of the files //file contains header and valid data entries, delimter = ',' std::ifstream file_header_data(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' std::ifstream file_header_data_2(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' std::ifstream file_header_data_3(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' std::ifstream file_header_data_4(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' std::ifstream file_header_data_5(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' std::ifstream file_header_data_6(csvFileWithHeader); //file contains no header an valid data entries, delimter = ',' std::ifstream file2(csvFileNoHeader); //file contains header and valid data entries, delimter = ';' std::ifstream file3(csvFileHeaderSemi); csv::CSVIterator it(file_header_data); it.setDelimiter(','); (void)++it; (void)++it; //if you iterate over the end of file, the last values //of the file will remain in the data structure but no //error occurs. (void)++it; (void)++it; //------------------------------------------------------------------- // a possiblity to get the data out of the iterator std::tuple value = *it; // // Show the value of one iterator // LOG_INFO( "Values are: "); LOG_INFO(std::get<0>(value) ); LOG_INFO(std::get<1>(value) ); //-------------------------------------------------------------------- //testing differnet parameters to the constructor //uncomment to see that it is not possible to iterate over an vector in the tuple. //rosa::csv::CSVIterator> it2(file, 1); //try to skip a valid number of lines after the header csv::CSVIterator it2_0(file_header_data_2, 1); //try to skip a valid number of lines after the header, but you assume that the file has no header //uncomment this line to crash the programm //csv::CSVIterator it2_1(file_header_data_3, 0, csv::HeaderInformation::HasNoHeader); //try to skip a valid number of lines after the header, but you assume that the file has no header //uncomment this line to crash the program //csv::CSVIterator it2_2(file_header_data_4, 1, csv::HeaderInformation::HasNoHeader); //try to skip a valid number of lines of a file without header csv::CSVIterator it2_3(file2, 1, csv::HeaderInformation::HasNoHeader); //try to skip a valid number of lines after the header, but with different delimiter csv::CSVIterator it2_4(file3, 2, csv::HeaderInformation::HasHeader, ';'); // if you skip more lines than valid, you generate an infinte loop //csv::CSVIterator it3(file_header_data_5, 500); //if you don't need data from all columns just select the number of columns you //need. You get the data back from the first column (index 0) to the fourth column //all values from the fifth column are ignored. csv::CSVIterator it4(file_header_data_6); } /// /// This function tests the basic CSVTupleWriter capablities, and shows you /// how you could work with this class. /// void testtupleCSVWriter(void){ // // Create output writer with an file // std::ofstream file_header_out(csvFileWriteHea); csv::CSVTupleWriter wri(file_header_out); // // Create test tuples // std::tuple values(5, 8.3f, "hallo"); std::tuple values2(3, 8.3f, "end"); // // Create test header lines for the test tuples // std::array header{ {"zero column", "first column", "second column"}}; std::array headerWrong{ {"zero column", "first column", "second column", "third column"}}; std::array headerWrongShort{ {"zero column", "first column"}}; //if you uncomment this line than it would be possible for you to write the header into the stream //in the next line. //wri.write(values); wri.writeHeader(header); wri.write(values); wri.write(values); // it is not possible to write an additional header into the stream. wri.writeHeader(header); wri.write(values); wri << values; wri << values2; //uncomment this line to see, that you can't write a header with the too many elements. //wri.writeHeader(headerWrong); //uncomment this line to see, that you can't write a header with the too few elements. //wri.writeHeader(headerWrongShort); } /// /// This function tests the basic splitTupleIterator capablities, and shows you /// how you could work with this class, this class is used if you want to split /// a CSVIterator in separate parts. /// void testsplitTupleIterator(void) { // // Create application // std::unique_ptr App = app::Application::create(ExampleName); // // Create application sensors. // LOG_INFO("Creating sensors."); // All sensors are created without defining a normal generator function, but // with the default value of the second argument. That, however, requires the // data type to be explicitly defined. This is good for simulation only. // Three different sensors were created, this is just a random number taken. AgentHandle Elem0Sensor = App->createSensor("Element1 Sensor"); AgentHandle Elem1Sensor = App->createSensor("Element2 Sensor"); AgentHandle Elem2Sensor = App->createSensor("Element3 Sensor"); // // Initialize application for simulation. // App->initializeSimulation(); // Type aliases for iterators using Iterator = rosa::csv::CSVIterator; using IteratorValue = std::tuple; static_assert( std::is_same::value, "Iterator must provide tuples"); // // Open CSV file and register the columns to the corresponding sensors. // std::ifstream TestCSV(csvFileWithHeader); // // Test data looks like: // Element1, Element2, Element3, Element4, Element5 -- is the header line // 3, 5, 8, 9.5, 17 -- first line of values // 100, -8, 30, 18.8, 29 -- other line of values // were also in the file // 5, 20, -100, -200.1, -30 -- if you have less number // of values than simulation rounds all values // -- beyond your last value // will be zero. // get element iterator ranges auto[Elem0Range, Elem1Range, Elem2Range] = iterator::splitTupleIterator(Iterator(TestCSV), Iterator()); // dissect a range into begin and end iterators by structred bindings auto[Elem0Begin, Elem0End] = Elem0Range; // deissect a range with functions auto Elem1Begin = iterator::begin(Elem1Range); auto Elem1End = iterator::end(Elem1Range); App->registerSensorValues(Elem0Sensor, std::move(Elem0Begin), Elem0End); App->registerSensorValues(Elem1Sensor, std::move(Elem1Begin), Elem1End); App->registerSensorValues(Elem2Sensor, std::move(iterator::begin(Elem2Range)), iterator::end(Elem2Range)); // // Simulate. // App->simulate(NumberOfSimulationCycles); } /// /// This function tests the basic splitTupleWriter capablities, and shows you /// how you could work with this class, this class is used if you want to split /// a CSVWriter in separate parts. /// void testsplitTupleWriter(void){ // // Create output writer with an file // std::ofstream file_header_out(csvFileWriteNoHeaSplit); csv::CSVTupleWriter wri(file_header_out); // if you omit, the type definition in the template, than auto generated types were used, // and they may not fit to the used CSVTupleWriter. wri << std::make_tuple(1000, 50.6f, "tuple_created"); auto [T0Writer, T1Writer, T2Writer] = writer::splitTupleWriter(std::move(wri), writer::IncompleteTuplePolicy::Ignore); //writing elements in sequential order into the writer classes, but you can write the values into the writers in //a random order. T0Writer << (500); T1Writer << (3.0); T2Writer << "splitted writter"; T2Writer << "splitting is cool"; T0Writer << (-30); T1Writer << (-0.004f); // you can also write more often values into a writer and later into the other writers // all data will be processed correctly into the right order. T0Writer << (1); T0Writer << (2); T1Writer << (-0.4f); T0Writer << (3); T2Writer << "again"; T0Writer << (4); T1Writer << (-0.1f); T1Writer << (-0.2f); T2Writer << "and"; T1Writer << (-0.3f); T2Writer << "splitting"; T2Writer << "once again"; // again writing data of one tuple entry to the different writers in a random fashion. T1Writer << (-0.004f); T2Writer << "splitting is cool"; T0Writer << (-30); } int main(void) { LOG_INFO_STREAM << library_string() << " -- " << terminal::Color::Red << ExampleName << " example" << terminal::Color::Default << '\n'; // // Testing CSVWriter. // LOG_INFO("Testing CSVWriter CSVTupleItrator implementation: "); testtupleCSVWriter(); // // Testing CSVReader. // LOG_INFO("Testing CSVReader CSVTupleIterator implementation: "); testtupleCSVReader(); // // Testing SplitTupleIterator. // LOG_INFO("Testing SplitTupleIterator: "); testsplitTupleIterator(); // // Testing SplitTupleWriter. // LOG_INFO("Testing SplitTupleWriter: "); testsplitTupleWriter(); // // info that user knows programm has finished. // LOG_INFO("All tests finished."); return 0; }