Advertisement
Mike_be

Elevator Class

Dec 21st, 2017
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.52 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <fstream>
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <regex>
  8. #include <streambuf>
  9. #include <filesystem>
  10. #include <sstream>
  11. #include <iomanip>
  12.  
  13. using namespace std;
  14.  
  15. template <typename T>
  16. typename T::size_type levenshtein_distance(const T & src, const T & dst) //Template for Levenshtein distance to work with strings and vectors
  17. {
  18.     const typename T::size_type m = src.size();
  19.     const typename T::size_type n = dst.size();
  20.     if (m == 0)
  21.     {
  22.         return n;
  23.     }
  24.     if (n == 0)
  25.     {
  26.         return m;
  27.     }
  28.  
  29.     std::vector<std::vector<typename T::size_type>> matrix(m + 1);
  30.  
  31.     for (typename T::size_type i = 0; i <= m; ++i)
  32.     {
  33.         matrix[i].resize(n + 1);
  34.         matrix[i][0] = i;
  35.     }
  36.     for (typename T::size_type i = 0; i <= n; ++i)
  37.     {
  38.         matrix[0][i] = i;
  39.     }
  40.  
  41.     typename T::size_type above_cell, left_cell, diagonal_cell, cost;
  42.  
  43.     for (typename T::size_type i = 1; i <= m; ++i)
  44.     {
  45.         for (typename T::size_type j = 1; j <= n; ++j)
  46.         {
  47.             cost = src[i - 1] == dst[j - 1] ? 0 : 1;
  48.             above_cell = matrix[i - 1][j];
  49.             left_cell = matrix[i][j - 1];
  50.             diagonal_cell = matrix[i - 1][j - 1];
  51.             matrix[i][j] = std::min(std::min(above_cell + 1, left_cell + 1), diagonal_cell + cost);
  52.         }
  53.     }
  54.  
  55.     return matrix[m][n];
  56. }
  57.  
  58. #include <Windows.h>
  59.  
  60. using namespace std;
  61. using namespace experimental::filesystem;
  62.  
  63. HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); //Console address to change text color
  64.  
  65. inline bool print_str(string str, int k, int n) //Function for printing strings in specific color and with set speed
  66. {
  67.     SetConsoleTextAttribute(hConsole, k);
  68.     for (int l = 0; l < int(str.size()); l++)
  69.     {
  70.         cout << str[l];
  71.         Sleep(n);
  72.     }
  73.     SetConsoleTextAttribute(hConsole, 14);
  74.     return true;
  75. }
  76.  
  77. bool yes_no() //Function for getting choice from user
  78. {
  79.     bool err = false;
  80.     string temp;
  81.     getline(cin, temp);
  82.     do
  83.     {
  84.         err = false;
  85.         if (temp == "Yes" || temp == "yes" || temp == "y" || temp == "Y") return true; // Returning result for yes answer
  86.         else if (temp == "No" || temp == "no" || temp == "N" || temp == "n") return false; // For no answer
  87.         else
  88.         {
  89.             // If input is incorrect
  90.             print_str("Type [Yes] or [No]: ", 15, 15);
  91.             getline(cin, temp);
  92.             err = true;
  93.         }
  94.     } while (err);
  95.     cout << "An error occurred!" << endl;
  96.     return true;
  97. }
  98.  
  99. string make_path(string str, string folder) //Function for making path to specific folder to work with input files
  100. {
  101.     string extension = "";
  102.     folder += "/";
  103.     unsigned int j;
  104.     if (str.length() >= 4)
  105.     {
  106.         j = str.length() - 4;
  107.         for (int i = 0; i < 4; i++)
  108.         {
  109.             extension.push_back(str[j]);
  110.             j++;
  111.         }
  112.     }
  113.     if (extension == ".txt")
  114.         str = folder + str;
  115.     else
  116.         str = folder + str + ".txt";
  117.     return str;
  118. }
  119.  
  120. void filling_strings(vector<string>& vec) //Adds space to the end of string to make them equally long for better levenshtein counting
  121. {
  122.     unsigned int max_l = 0;
  123.     for (unsigned int i = 0; i < vec.size(); i++)
  124.     {
  125.         if (vec[i].length() > max_l)
  126.             max_l = vec[i].size();
  127.     }
  128.     for (unsigned int i = 0; i < vec.size(); i++)
  129.     {
  130.         while (vec[i].length() < max_l)
  131.             vec[i].push_back(' ');
  132.     }
  133. }
  134.  
  135. string shorting_string(string str) //Removes spaces from the end of string for printing
  136. {
  137.     while (str[str.length() - 1] == ' ')
  138.         str.pop_back();
  139.     return str;
  140. }
  141.  
  142. string vec_search(const vector<string>& vec, const string& str) //Searches closest result from vector of files
  143. {
  144.     unsigned int i = 0, k = 0, dist = 100;
  145.     while (k < vec.size())
  146.     {
  147.         if (levenshtein_distance(vec[k], str) < dist)
  148.         {
  149.             dist = levenshtein_distance(vec[k], str);
  150.             i = k;
  151.         }
  152.         k++;
  153.     }
  154.     return vec[i];
  155. }
  156.  
  157. bool empty(const string& str) //Checks if user wrote many spaces or just pressed enter
  158. {
  159.     bool empty = true;
  160.     if (!str.empty())
  161.     {
  162.         for (unsigned int i = 0; i < str.length(); i++)
  163.         {
  164.             if (str[i] != ' ')
  165.             {
  166.                 empty = false;
  167.             }
  168.         }
  169.     }
  170.     return empty;
  171. }
  172.  
  173. void files(vector<string>& vec, string& folder) //Searches all files in folder and puts in vector
  174. {
  175.     for (auto p : directory_iterator(folder))
  176.     {
  177.         vec.push_back(p.path().string());
  178.     }
  179.     filling_strings(vec);
  180. }
  181.  
  182. void check_files(vector<string>& vec, string& folder) //Checks if user added or changed files in folder to work with program without exiting it
  183. {
  184.     unsigned int i;
  185.     vector<string> vec_2;
  186.     bool same_name = true;
  187.     for (auto p : directory_iterator(folder))
  188.     {
  189.         vec_2.push_back(p.path().string());
  190.     }
  191.     filling_strings(vec_2);
  192.     if (vec_2.size() != vec.size())
  193.     {
  194.         vec.clear();
  195.         vec = vec_2;
  196.         filling_strings(vec);
  197.     }
  198.     else
  199.     {
  200.         if (vec.size() > vec_2.size())
  201.             i = vec_2.size();
  202.         else
  203.             i = vec.size();
  204.         for (unsigned j = 0; j < i; j++)
  205.         {
  206.             if (vec[j] != vec_2[j])
  207.             {
  208.                 vec = vec_2;
  209.                 return;
  210.             }
  211.         }
  212.     }
  213. }
  214.  
  215. class Elevator{
  216. public:
  217.     Elevator(int hh, char cc, int mm, int ss, int ee) //Method to initialize variables
  218.     :hours(hh), chr(cc), mins(mm), s_floor(ss), e_floor(ee), distance(set_dist()), time_travel(0), arrival_time_h(0), arrival_time_m(0)
  219.     {
  220.         check();
  221.         set_time_travel();
  222.         set_arrival();
  223.         return;
  224.     };
  225.     Elevator() :hours(0), chr(':'), mins(0), s_floor(1), e_floor(1), distance(0), time_travel(0), arrival_time_h(0), arrival_time_m(0) {}; //Default case
  226.     //Methods to return variables from private state
  227.     int get_hours() const
  228.     {
  229.         return hours;
  230.     }
  231.     char get_chr() const
  232.     {
  233.         return chr;
  234.     }
  235.     int get_mins() const
  236.     {
  237.         return mins;
  238.     }
  239.     int get_s_floor() const
  240.     {
  241.         return s_floor;
  242.     }
  243.     int get_e_floor() const
  244.     {
  245.         return e_floor;
  246.     }
  247.     int get_distance() const
  248.     {
  249.         return distance;
  250.     }
  251.     int get_time_travel() const
  252.     {
  253.         return time_travel;
  254.     }
  255.     int get_arrival_h() const
  256.     {
  257.         return arrival_time_h;
  258.     }
  259.     int get_arrival_m() const
  260.     {
  261.         return arrival_time_m;
  262.     }
  263.     bool operator==(const Elevator& ele_1) const
  264.     {
  265.         return (ele_1.hours == hours &&
  266.                 ele_1.mins == mins &&
  267.                 ele_1.s_floor == s_floor &&
  268.                 ele_1.e_floor == e_floor);
  269.     }
  270. private:
  271.     void check() //Function for check
  272.     {
  273.         check_hours();
  274.         check_mins();
  275.         check_char();
  276.         //check_floors(); //Remove this command from comments if your building doesn't have basement floors
  277.     }
  278.     void check_hours() //Checks hours
  279.     {
  280.         if (hours < 0 || arrival_time_h < 0)
  281.         {
  282.             print_str("Negative hours, huh? I see you are the clever one. \n", 12, 10);
  283.             throw runtime_error("Type again: ");
  284.         }
  285.         else if (hours > 24 || arrival_time_h > 24)
  286.         {
  287.             print_str("There is no way to have more than 24 hours in day. \n", 12, 10);
  288.             throw runtime_error("Type again: ");
  289.         }
  290.         else if ((hours == 24 && mins < 60) || (arrival_time_h == 24 && mins < 60))
  291.         {
  292.             print_str("Day can't have more than 24, so i changed 24:mins to 00:mins. \n", 11, 10);
  293.             hours = 0;
  294.         }
  295.     }
  296.     void check_mins() //checks minutes
  297.     {
  298.         if (mins < 0 || arrival_time_m < 0)
  299.         {
  300.             print_str("Why would you write negative minutes? World doesn't work like this. \n", 4, 10);
  301.             throw runtime_error("Type again: ");
  302.         }
  303.         else if (mins > 60 || arrival_time_m > 60)
  304.         {
  305.             print_str("No way there is more than 60 minutes in hour. \n", 4, 10);
  306.             throw runtime_error("Type again: ");
  307.         }
  308.         else if (mins == 60 || arrival_time_m == 60)
  309.         {
  310.             print_str("You had 60 minutes, so i changed it to 00 mins and added 1 hours. \n", 3, 10);
  311.             if (mins == 60) {
  312.                 mins = 0;
  313.                 hours++;
  314.             }
  315.             else
  316.             {
  317.                 arrival_time_m = 0;
  318.                 arrival_time_h++;
  319.             }
  320.             check_hours();
  321.         }
  322.     }
  323.     void check_char() //Checks char between hours and minutes
  324.     {
  325.         if (chr != ':')
  326.         {
  327.             print_str("Hey, i don't understand, what is this ", 15, 10); cout << chr; print_str(" ? Why did you use it? \n", 15, 10);
  328.             throw runtime_error("Type again: ");
  329.         }
  330.         return;
  331.     }
  332.     void check_floors() //Checks basement floors
  333.     {
  334.         if (s_floor < 1 || e_floor < 1)
  335.         {
  336.             print_str("Do you have basement floors? Sorry, but they are not supported in this program. \n", 2, 10);
  337.             throw runtime_error("Type again: ");
  338.         }
  339.     }
  340.     int set_dist() //Calculates travel distance
  341.     {
  342.         if (s_floor > e_floor)
  343.             distance = s_floor - e_floor;
  344.         else if (e_floor > s_floor)
  345.             distance = e_floor - s_floor;
  346.         else
  347.         {
  348.             print_str("Why would you call elevator and go to the same floor?", 13, 10);
  349.             distance = 0;
  350.         }
  351.         return distance;
  352.     }
  353.     void set_time_travel()
  354.     {
  355.         time_travel = distance*floor_time;
  356.     }
  357.     void set_arrival() //Calculates travel time based on
  358.     {
  359.         arrival_time_h = hours;
  360.         arrival_time_m = mins + time_travel;
  361.         while (arrival_time_m >= 60)
  362.         {
  363.             arrival_time_m -= 60;
  364.             arrival_time_h++;
  365.         }
  366.         while (arrival_time_h >= 24)
  367.             arrival_time_h -= 24;
  368.         check();
  369.     }
  370.     int hours, mins, s_floor, e_floor, distance, time_travel, arrival_time_h, arrival_time_m;
  371.     double floor_time = 1.2; //In minutes, yes, very slow elevator. Or very high ceilings in floors
  372.     char chr;
  373.    
  374. };
  375.  
  376. ostream& operator<< (ostream& os, const Elevator& tm) //Reloading output operator
  377. {
  378.     char old_fill = os.fill('0');
  379.     os << setw(2) << tm.get_hours() << tm.get_chr() << setw(2) << tm.get_mins(); print_str(" - Time of elevator call", 15, 10);
  380.     os << endl << tm.get_s_floor(); print_str(" - Floor where elevator was called", 15, 10);
  381.     os << endl << tm.get_e_floor(); print_str(" - Destination floor", 15, 10);
  382.     os << endl << tm.get_distance(); print_str(" - Travel distance", 15, 10);
  383.     os << endl << tm.get_time_travel(); print_str(" minutes - Travel time", 15, 10);
  384.     os << endl << tm.get_arrival_h() << tm.get_chr() << tm.get_arrival_m(); print_str(" - Arrival time", 15, 10);
  385.     os << endl << setfill(old_fill);
  386.     return os;
  387. }
  388.  
  389. ostream& operator<< (ostream& os, const vector<Elevator>& tm) //Reloading output operator for vector class
  390. {
  391.     for (unsigned int i = 0; i < tm.size(); i++)
  392.     {
  393.         os << tm[i] << endl;
  394.     }
  395.     return os;
  396. }
  397.  
  398. istream& operator>> (istream& is, Elevator& ele) //Reloading of input operator
  399. {
  400.     int h, m, f1, fe;
  401.     char ch;
  402.     is >> h >> ch >> m >> f1 >> fe;
  403.     if (!is)
  404.         return is;
  405.     try
  406.     {
  407.         ele = Elevator(h, ch, m, f1, fe);
  408.     }catch (runtime_error& e)
  409.     {
  410.         is.clear(ios_base::failbit);
  411.     }
  412.     return is;
  413. }
  414.  
  415. void stats(vector<Elevator>& vec) //Function to get all statistics from class vector and print it
  416. {
  417.     int all_travel = 0, all_time = 0;
  418.     for (unsigned int i = 0; i < vec.size(); i++)
  419.     {
  420.         all_travel += vec[i].get_distance();
  421.         all_time += vec[i].get_time_travel();
  422.     }
  423.     print_str("Elevator were called ", 15, 10); cout << vec.size(); print_str(" times today.\n", 15, 10);
  424.     print_str("It traveled ", 15, 10); cout << all_travel; print_str(" floors in total.\n", 15, 10);
  425.     print_str("It traveled for ", 15, 10); cout << all_time; print_str(" minutes in total.\n", 15, 10);
  426. }
  427.  
  428. bool call(vector<Elevator>& vec, string& choice) //Function to call different commands
  429. {
  430.     string help = "help", stat = "stats", clear = "clear", dummy, show = "show all";
  431.     if (levenshtein_distance(choice, help) < 2)
  432.     {
  433.         print_str(
  434.             "Hello, you have used \"help\" command, and here i am.\nYou can type \"help\" to see this text again, you can also use:\n",
  435.             10, 10);
  436.         cout << "\"stats\" ";
  437.         print_str(
  438.             "to call overall stats for this day, how many times elevator was called  and total travel distance;\n",
  439.             10, 10);
  440.         cout << "\"clear\" ";
  441.         print_str("to clear today's calls and start a \"New Day\";\n", 10, 10);
  442.         cout << "\"show all\" ";
  443.         print_str(" to show all saved variables.\n", 10, 10);
  444.         print_str("You can call them whenever you want (except when you need to write file's name)\n", 10, 15);
  445.         print_str("Press Enter to continue.", 7, 10);
  446.         getline(cin, dummy);
  447.         return true;
  448.     }
  449.     else if (levenshtein_distance(choice, stat) < 2)
  450.     {
  451.         stats(vec);
  452.         print_str("Press Enter to continue.", 7, 10);
  453.         getline(cin, dummy);
  454.         return true;
  455.     }
  456.     else if (levenshtein_distance(choice, clear) < 2)
  457.     {
  458.         vec.clear();
  459.         print_str("Day was cleared.\n", 15, 10);
  460.         print_str("Press Enter to continue.", 7, 10);
  461.         getline(cin, dummy);
  462.         return true;
  463.     }
  464.     else if (levenshtein_distance(choice, show) < 3)
  465.     {
  466.         print_str("All variables:\n", 15, 10);
  467.         cout << vec;
  468.         print_str("Press Enter to continue.", 7, 10);
  469.         getline(cin, dummy);
  470.         return true;
  471.     }
  472.     return false;
  473. }
  474.  
  475. bool yes_no(vector<Elevator>& vec, const string& mes) //Function to get answer from user from before, but reloaded with different variables and calling previous function
  476. {
  477.     bool err = false, cal;
  478.     string temp;
  479.     print_str(mes, 15, 10);
  480.     getline(cin, temp);
  481.     do
  482.     {
  483.         cal = call(vec, temp);
  484.         err = false;
  485.         if (cal)
  486.         {
  487.             while (cal)
  488.             {
  489.                 print_str(mes, 15, 10);
  490.                 getline(cin, temp);
  491.                 cal = call(vec, temp);
  492.             }
  493.         }
  494.         if (temp == "Yes" || temp == "yes" || temp == "y" || temp == "Y") return true; // Returning result for yes answer
  495.         else if (temp == "No" || temp == "no" || temp == "N" || temp == "n") return false; // For no answer
  496.         else
  497.         {
  498.             // If input is incorrect
  499.             print_str("Type [Yes] or [No]: ", 15, 15);
  500.             getline(cin, temp);
  501.             err = true;
  502.         }
  503.     } while (err);
  504.     cout << "An error occurred!" << endl;
  505.     return true;
  506. }
  507.  
  508. void file_work(vector<string>& vec, string& read, string folder) //Function to do all work with files
  509. {
  510.     files(vec, folder);
  511.     string file;
  512.     print_str("Write file's name: ", 15, 10);
  513.     do
  514.     {
  515.         getline(cin, file);
  516.     } while (empty(file) && cout << "Why would you write nothing? Type again: ");
  517.     ifstream in;
  518.     check_files(vec, folder);
  519.     in.open(make_path(file, folder));
  520.     if (!in.is_open()) //If file isn't open, it asks user if he meant file
  521.     {
  522.         print_str("Did you mean \"", 15, 10);
  523.         cout << shorting_string(vec_search(vec, make_path(file, folder)));
  524.         print_str("\"?\n", 15, 10);
  525.         if (yes_no())
  526.             in.open(vec_search(vec, make_path(file, folder)));
  527.     }
  528.     read.assign((istreambuf_iterator<char>(in)), //Assigns to string from input buffer
  529.                  istreambuf_iterator<char>());
  530. }
  531.  
  532. int main()
  533. {
  534.     print_str("Hello, you can write elevator schedule here, it will save all of them until you reset it.\nType \"help\" for mote info\n", 11, 10);
  535.     vector<Elevator> day;
  536.     vector<string> files;
  537.     Elevator ele, base;
  538.     string dummy, read;
  539.     do
  540.     {
  541.         if (yes_no(day, "Do you want to read from file?\n"))
  542.         {
  543.             file_work(files, read, "Input");
  544.             cout << read << endl;
  545.             istringstream in(read);
  546.             while (in)
  547.             {
  548.                 in >> ele;
  549.                 day.push_back(ele);
  550.             }
  551.             day.pop_back();
  552.         }
  553.         else
  554.         {
  555.             print_str("Write your stuff: ", 15, 10);
  556.             do
  557.             {
  558.                 getline(cin, dummy);
  559.                 call(day, dummy);
  560.                 istringstream in(dummy);
  561.                 while (in)
  562.                 {
  563.                     in >> ele;
  564.                     day.push_back(ele);
  565.                 }
  566.                 day.pop_back();
  567.             }
  568.             while (ele == base && print_str("Type again: ", 15, 10));
  569.         }
  570.         ele = base;
  571.     } while (yes_no(day, "Continue?\n"));
  572. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement