diff --git a/.gitignore b/.gitignore index 03409fc..cabe5e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -# Solution solution* # Prerequisites diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f720987 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,60 @@ +{ + "files.associations": { + "random": "cpp", + "optional": "cpp", + "*.tcc": "cpp", + "set": "cpp", + "fstream": "cpp", + "functional": "cpp", + "istream": "cpp", + "limits": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "streambuf": "cpp", + "tuple": "cpp", + "map": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "mutex": "cpp", + "new": "cpp", + "stdexcept": "cpp", + "thread": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/.vscode/settings.json:Zone.Identifier b/.vscode/settings.json:Zone.Identifier new file mode 100644 index 0000000..7135310 --- /dev/null +++ b/.vscode/settings.json:Zone.Identifier @@ -0,0 +1,3 @@ +[ZoneTransfer] +ZoneId=3 +ReferrerUrl=C:\Users\matan\Downloads\NumberWithUnitsApart-main (1).zip diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dac2373 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Erel Segal-Halevi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index 57b5112..55e14d2 100644 --- a/Makefile +++ b/Makefile @@ -2,28 +2,43 @@ CXX=clang++-9 CXXFLAGS=-std=c++2a -Werror -Wsign-conversion +VALGRIND_FLAGS=-v --leak-check=full --show-leak-kinds=all --error-exitcode=99 SOURCES=NumberWithUnits.cpp OBJECTS=$(subst .cpp,.o,$(SOURCES)) -run: demo - ./$^ +run: test1 test2 test3 -demo: Demo.o $(OBJECTS) - $(CXX) $(CXXFLAGS) $^ -o demo +test1: TestRunner.o StudentTest1.o $(OBJECTS) + $(CXX) $(CXXFLAGS) $^ -o $@ -test: TestCounter.o Test.o $(OBJECTS) - $(CXX) $(CXXFLAGS) $^ -o test +test2: TestRunner.o StudentTest2.o $(OBJECTS) + $(CXX) $(CXXFLAGS) $^ -o $@ -tidy: - clang-tidy $(SOURCES) -checks=bugprone-*,clang-analyzer-*,cppcoreguidelines-*,performance-*,portability-*,readability-*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-owning-memory --warnings-as-errors=-* -- +test3: TestRunner.o StudentTest3.o $(OBJECTS) + $(CXX) $(CXXFLAGS) $^ -o $@ -# your_test_our_class: NumberWithUnitsTest.cpp -# $(CXX) $(CXXFLAGS) NumberWithUnitsTest.cpp -o your_test_our_class +main: Main.o $(OBJECTS) + $(CXX) $(CXXFLAGS) $^ -o main -%.o: %.cpp +%.o: %.cpp $(HEADERS) $(CXX) $(CXXFLAGS) --compile $< -o $@ +StudentTest1.cpp: # Shlomo Glick + curl https://raw.githubusercontent.com/shlomog12/ex3_partA/main/Test.cpp > $@ + +StudentTest2.cpp: # Yair Raviv + curl https://raw.githubusercontent.com/yairaviv/NumberWithUnits_a/main/Test.cpp > $@ + +StudentTest3.cpp: # Roei Birger + curl https://raw.githubusercontent.com/roei-birger/CPP_course_p3/master/Test.cpp > $@ + +tidy: + clang-tidy $(SOURCES) -extra-arg=-std=c++2a -checks=bugprone-*,clang-analyzer-*,cppcoreguidelines-*,performance-*,portability-*,readability-*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-owning-memory,-readability-isolate-declaration --warnings-as-errors=-* -- + +valgrind: test1 + valgrind --leak-check=full --error-exitcode=99 --tool=memcheck $(VALGRIND_FLAGS) ./test1 clean: - rm -f *.o demo test + rm -f *.o test* + rm -f StudentTest*.cpp diff --git a/NumberWithUnits.cpp b/NumberWithUnits.cpp index b56e479..aa48c1f 100644 --- a/NumberWithUnits.cpp +++ b/NumberWithUnits.cpp @@ -4,133 +4,159 @@ #include #include #include +#include "graph.cpp" #include "NumberWithUnits.hpp" -// #define BOOL true using namespace std; -//m -> cm -//cm -> m -//km -> m -//m -> km + namespace ariel { - static map> convertor; // convertor O(3) + static graph g; - double convertHelp(const string &from, const string &to, double fromVal) - { - if (from == to) - { + double NumberWithUnits::convert(const string &from, const string &to, double fromVal){ + if(from == to){ return fromVal; } - if (convertor.at(from).count(to) != 0) - { - return fromVal * convertor.at(from).at(to); + double retVal = g.getConv(from, to); + if(retVal > -1){ + return fromVal*retVal; } - __throw_invalid_argument("Not valid convertion"); - + __throw_invalid_argument("Not valid convertion"); } - double convert(const string &from, const string &to, double fromVal) - { - if (from == to) - { - return fromVal; - } - if (convertor.at(from).count(to) != 0) + void NumberWithUnits::read_units(ifstream &f) + { + string num1; + string num2; + string n; + string l; + double value1 = 0; + double value2 = 0; + while (getline(f, l)) { - return fromVal * convertor.at(from).at(to); + istringstream Sstream(l); + if (!(Sstream >> value1 >> num1 >> n >> value2 >> num2)) + { + break; + } + g.addEdge(num1 ,num2, (value2/value1)); } - map m = convertor.at(from); - string s; - for (map::iterator it = m.begin(); it != m.end(); ++it) + } + NumberWithUnits::NumberWithUnits(const double& value, const string &unit){ + if (!g.checkExist(unit)) { - s = it->first; + __throw_invalid_argument("Invalid unit"); } - return convertHelp(s, to, convert(from, s, fromVal)); + num=value; + the_unit=unit; } - void NumberWithUnits::read_units(ifstream &file) + int comparison(const NumberWithUnits& num1, const NumberWithUnits& num2) { - double Dunit1 = 0; - double Dunit2 = 0; - string Munit1; - string Munit2; - string none; - string line; - while (getline(file, line)) + double x = num1.num - NumberWithUnits::convert(num2.the_unit, num1.the_unit, num2.num); + double y = NumberWithUnits::convert(num2.the_unit, num1.the_unit, num2.num) - num1.num; + const double epsilon = 0.00001; + if (x > epsilon) { - istringstream Sstream(line); - if (!(Sstream >> Dunit1 >> Munit1 >> none >> Dunit2 >> Munit2)) - { - break; - } - - convertor[Munit1][Munit2] = Dunit2; //from - convertor[Munit2][Munit1] = 1 / Dunit2; //to + return 1; + } + if (y > epsilon) + { + return -1; } + return 0; } - NumberWithUnits operator+(const NumberWithUnits &unit1, const NumberWithUnits &unit2) - { - double converted = convert(unit2._unit, unit1._unit, unit2._value); - return NumberWithUnits(unit1._value + converted, unit1._unit); + // in/out + + ostream &operator<<(ostream &os, const NumberWithUnits &number) { + return (os << number.num << '[' << number.the_unit << ']'); } - NumberWithUnits operator+=(NumberWithUnits &unit1, const NumberWithUnits &unit2) + istream &operator>>(std::istream &is, NumberWithUnits &unit) { - unit1._value += convert(unit2._unit, unit1._unit, unit2._value); - return unit1; + string s; + double number = 0; + char c = ']'; + is >> number >> c; + while(c != ']'){ + if(c != '['){ + s.insert(s.end(), c); + } + is >> c; + } + unit.num = number; + unit.the_unit = s; + if(!g.checkExist(unit.the_unit)){ + __throw_invalid_argument("Unit is not exist"); + } + return is; } - NumberWithUnits operator+(const NumberWithUnits &unit, double num) + + + NumberWithUnits operator+(const NumberWithUnits &num1, const NumberWithUnits &num2) { - return NumberWithUnits(unit._value + num, unit._unit); + double converted = NumberWithUnits::convert(num2.the_unit, num1.the_unit, num2.num); + return NumberWithUnits(num1.num + converted, num1.the_unit); } - NumberWithUnits operator-(const NumberWithUnits &unit1, const NumberWithUnits &unit2) - { - double converted = convert(unit2._unit, unit1._unit, unit2._value); - return NumberWithUnits(unit1._value - converted, unit1._unit); + NumberWithUnits operator+(const NumberWithUnits& num1, double num) { + return NumberWithUnits(num1.num + num, num1.the_unit); } - NumberWithUnits operator-=(NumberWithUnits &unit1, const NumberWithUnits &unit2) + NumberWithUnits& NumberWithUnits::operator+=(const NumberWithUnits &num2) { - unit1._value -= convert(unit2._unit, unit1._unit, unit2._value); - return unit1; + double con = convert(num2.the_unit, this->the_unit, num2.num); + this->num += con; + return *this; } - NumberWithUnits operator-(const NumberWithUnits &unit) + NumberWithUnits operator-(const NumberWithUnits &num1, const NumberWithUnits &num2) { - return NumberWithUnits(-unit._value, unit._unit); + double converted = NumberWithUnits::convert(num2.the_unit, num1.the_unit, num2.num); + return NumberWithUnits(num1.num - converted, num1.the_unit); } - int compare(const NumberWithUnits &n1, const NumberWithUnits &n2) + NumberWithUnits operator-(const NumberWithUnits& num1, double num){ + return NumberWithUnits(num1.num - num, num1.the_unit); + } + NumberWithUnits& NumberWithUnits::operator-=(const NumberWithUnits &num2) { - double x = n1._value - convert(n2._unit, n1._unit, n2._value); - double y = convert(n2._unit, n1._unit, n2._value) - n1._value; - const double epsilon = 0.00001; - if (x > epsilon) - { - return 1; - } - if (y > epsilon) - { - return -1; - } - return 0; + double con = convert(num2.the_unit, this->the_unit, num2.num); + this->num -= con; + return *this; } + - bool operator>(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) > 0; } - bool operator>=(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) >= 0; } - bool operator<(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) < 0; } - bool operator<=(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) <= 0; } - bool operator==(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) == 0; } - bool operator!=(const NumberWithUnits &unit1, const NumberWithUnits &unit2) { return compare(unit1, unit2) != 0; } - NumberWithUnits operator++(NumberWithUnits &unit) { return NumberWithUnits(++unit._value, unit._unit); } //Prefix - NumberWithUnits operator++(NumberWithUnits &unit, int) { return NumberWithUnits(unit._value++, unit._unit); } //Postfix - NumberWithUnits operator--(NumberWithUnits &unit) { return NumberWithUnits(--unit._value, unit._unit); } //Prefix - NumberWithUnits operator--(NumberWithUnits &unit, int) { return NumberWithUnits(unit._value++, unit._unit); } //Postfix - NumberWithUnits operator*(const NumberWithUnits &unit, double num) { return NumberWithUnits(num * unit._value, unit._unit); } - NumberWithUnits operator*(double num, const NumberWithUnits &unit) { return NumberWithUnits(num * unit._value, unit._unit); } - ostream &operator<<(const ostream &os, const NumberWithUnits &unit) { return cout << unit._value << "[" << unit._unit << "]" << endl; } - istream &operator>>(std::istream &in, NumberWithUnits &unit) - { - string s; - in >> unit._value >> s >> unit._unit; - return in; + + // bool operators + bool operator>(const NumberWithUnits &num1, const NumberWithUnits &num2) { return comparison(num1, num2) > 0; } + bool operator>=(const NumberWithUnits &num1, const NumberWithUnits &num2) { return comparison(num1, num2) >= 0; } + bool operator<(const NumberWithUnits &num1, const NumberWithUnits &num2) { return comparison(num1, num2) < 0; } + bool operator<=(const NumberWithUnits &num1, const NumberWithUnits &num2) { return comparison(num1, num2) <= 0; } + bool operator==(const NumberWithUnits &num1, const NumberWithUnits &num2) { return comparison(num1, num2) == 0; } + bool operator!=(const NumberWithUnits &num1, const NumberWithUnits &num2) { return comparison(num1, num2) != 0; } + + + // increment/decrement + NumberWithUnits& operator++(NumberWithUnits &number) { + ++number.num; + return number; + } + NumberWithUnits operator++(NumberWithUnits &number, int) { + NumberWithUnits temp = number; + number.num++; + return temp; + } + NumberWithUnits& operator--(NumberWithUnits &number) { + --number.num; + return number; + } + NumberWithUnits operator--(NumberWithUnits &number, int) { + NumberWithUnits temp = number; + number.num--; + return temp; + } + NumberWithUnits operator*(const NumberWithUnits &unit, double n) { + return NumberWithUnits{unit.num*n, unit.the_unit}; + } + NumberWithUnits operator*(double n, const NumberWithUnits &unit) { + return NumberWithUnits{unit.num*n, unit.the_unit}; } + } diff --git a/NumberWithUnits.hpp b/NumberWithUnits.hpp index 46acb45..7c8828e 100644 --- a/NumberWithUnits.hpp +++ b/NumberWithUnits.hpp @@ -6,39 +6,53 @@ using namespace std; namespace ariel{ class NumberWithUnits{ private: - double _value; - string _unit; + double num; + string the_unit; public: - const bool BOOL = true; - NumberWithUnits(double value, string unit){ - _value=value; - _unit=unit; - } + NumberWithUnits(const double& value, const string& unit); NumberWithUnits(){} ~NumberWithUnits(){} - friend int compare(const NumberWithUnits& n1, const NumberWithUnits& n2); - double convert(const string &from, const string &to, double fromVal); - double convertHelp(const string &from, const string &to, double fromVal); + + + static double convert(const std::string &from, const std::string &to, double fromVal); static void read_units(ifstream& file); + friend int comparison(const NumberWithUnits& n1, const NumberWithUnits& n2); + + // in/out + friend ostream& operator<<(ostream& os, const NumberWithUnits& unit); + friend istream& operator>>(istream& in, NumberWithUnits& unit); + + // plus/minus friend NumberWithUnits operator+(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator+=(NumberWithUnits& unit1, const NumberWithUnits& unit2); friend NumberWithUnits operator+(const NumberWithUnits& unit, double num); + NumberWithUnits& operator+=(const NumberWithUnits& unit2); friend NumberWithUnits operator-(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator-=(NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator-(const NumberWithUnits& unit); + friend NumberWithUnits operator-(const NumberWithUnits& unit1, double num); + NumberWithUnits& operator-=(const NumberWithUnits& unit2); + const NumberWithUnits operator+() const{ + return NumberWithUnits(+num, the_unit); + } + const NumberWithUnits operator-() const{ + return NumberWithUnits(-num, the_unit); + } + + + // bool operators friend bool operator>(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend bool operator>=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator<(const NumberWithUnits& unit1, const NumberWithUnits& unit2); + friend bool operator>=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator<=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator==(const NumberWithUnits& unit1, const NumberWithUnits& unit2); friend bool operator!=(const NumberWithUnits& unit1, const NumberWithUnits& unit2); - friend NumberWithUnits operator++( NumberWithUnits& unit); //Prefix - friend NumberWithUnits operator++( NumberWithUnits& unit, int); //Postfix - friend NumberWithUnits operator--( NumberWithUnits& unit); //Prefix - friend NumberWithUnits operator--( NumberWithUnits& unit, int); //Postfix - friend NumberWithUnits operator*(const NumberWithUnits& unit, double num); - friend NumberWithUnits operator*(double num, const NumberWithUnits& unit); - friend ostream& operator<<(const ostream& os, const NumberWithUnits& unit); - friend istream& operator>>(istream& in, NumberWithUnits& unit); + + // increment/decrement + friend NumberWithUnits& operator++( NumberWithUnits& number); + friend NumberWithUnits operator++( NumberWithUnits& number, int); + friend NumberWithUnits& operator--( NumberWithUnits& number); + friend NumberWithUnits operator--( NumberWithUnits& number, int); + + friend NumberWithUnits operator*(const NumberWithUnits& unit, double n); + friend NumberWithUnits operator*(double n, const NumberWithUnits& unit); + }; } \ No newline at end of file diff --git a/README.md b/README.md index b03577f..0a6d9a8 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,43 @@
-# מספרים עם יחידות - שלב א +# מספר עם יחידות - חלק ב -בשנת 1999, לוויין של נאס"א בשווי של 125 מיליון דולר התרסק בגלל אי-התאמה ביחידות - אחד הצוותים שפיתחו את הלוויין עבד ביחידות מטריות והצוות השני עבד ביחידות בריטיות (ראו דוגמאות נוספות -[כאן](http://mentalfloss.com/article/25845/quick-6-six-unit-conversion-disasters)). +כתבו מחלקה לניהול מספר עם יחידות, בהתאם להוראות בחלק א. -כדי שזה לא יקרה שוב, הם שכרו אתכם וביקשו מכם לכתוב מחלקה המייצגת מספר עם יחידות. במחלקה הזאת אפשר, למשל, לייצג את המספר "3 מטר" ואת המספר "40 סנטימטר", והסכום שלהם לא יהיה 43 אלא 3.4 מטר - המחלקה תדאג לבצע את ההמרה המתאימה. בנוסף, המחלקה לא תאפשר לחבר מספרים עם מימדים לא תואמים, למשל, חיבור של "3 מטר" עם "5 שניות" יגרום לזריקת חריגה. +בשלב ב עליכם לכתוב מימוש מלא. המימוש צריך לעבור את כל הבדיקות (60% מהציון): -הגדירו מחלקה בשם `NumberWithUnits` עם הפעולות הבאות (ראו בקובץ המצורף [Demo.cpp](Demo.cpp)): - -* פונקציה בשם `read_units`, הקוראת את היחידות מתוך קובץ טקסט. קובץ טקסט לדוגמה נמצא [כאן](units.txt). -* שישה אופרטורים חשבוניים: חיבור (+) הוספה (+=) פלוס אונרי (+), ושלושת האופרטורים המקבילים לחיסור (-). כאמור, חיבור של שני מספרים מאותו מימד יתבצע תוך המרת היחידה של המספר השני ליחידה של המספר הראשון; חיבור של שני מספרים ממימדים שונים יגרום לחריגה. -* שישה אופרטורי השוואה: גדול, גדול-או-שווה, קטן, קטן-או-שווה, שווה, לא-שווה, לפי אותם כללים של האופרטורים החשבוניים. -* הגדלה ב-1 (++) והקטנה ב-1 (--) לפני ואחרי המספר. -* הכפלה במספר ממשי (`double`). שימו לב: אין צורך לממש הכפלה של שני עצמים מסוג `NumberWithUnits`, -אלא רק `NumberWithUnits` כפול `double`. ההכפלה לא משנה את היחידות. -* אופרטור קלט ואופרטור פלט. - -הערות לגבי קובץ המרת היחידות: - -* אין חשיבות לרווח-לבן (אפשר לדלג על רווחים). -* הקובץ כולל מספר פקודות של המרת-יחידות. כל פקודה מתחילה ב"1", אחריה שם של יחידה, אחריה סימן "=", אחריה מספר כלשהו, ואחריה שם של יחידה אחרת. ראו דוגמה בקובץ [units.txt](units.txt). -* יחידות שאינן נמצאות בקובץ-היחידות נחשבות לא חוקיות: ניסיון לאתחל מספר עם יחידות כאלו יביא לזריקת חריגה. -* יחידות המוגדרות בקובץ-היחידות נחשבות חוקיות: אין צורך לבדוק שהנתונים בקובץ מתאימים למציאות. -* יש הבדל בין אותיות גדולות לקטנות. לדוגמה, אם בקובץ מוגדר "km" אז רק "km" נחשב חוקי - לא "KM" או "Km". - -הערות לגבי קלט ופלט: +
-* פורמט הפלט של מספר עם יחידות הוא: המספר, אחריו (בלי רווח) סוגריים מרובעים, ובתוכן היחידות. ראו דוגמה בקובץ Demo.cpp. -* פורמט הקלט הוא דומה, פרט לכך שמותר שיהיו רווחים לבנים (מותר לדלג על רווחים בקריאה). + make test + ./test +
-בשלב א עליכם לכתוב: +בנוסף, הקוד צריך לעבור בהצלחה את מבחן הקריאות (20% מהציון): -* קובץ כותרת הכולל את כל הפונקציות הדרושות (ללא מימוש). שימו לב: הכותרות צריכות להיות נכונות בהתאם למה שנלמד בהרצאות - מומלץ לחזור על החומר לפני שמתחילים לכתוב. -* בדיקות מקיפות לכל הפונקציות הדרושות. - * אין צורך לבדוק קריאה של קובץ-יחידות עם פורמט שגוי. +
+ make tidy +
-כיתבו את כל הקבצים הדרושים כך שהפקודות הבאות יעבדו ללא שגיאות: +ואת מבחן הזיכרון (20% מהציון):
- make demo && ./demo - make test && ./test + make valgrind
-מומלץ גם להריץ `make tidy`. +בנוסף, יש לכתוב **תוכנית ראשית** כלשהי המדגימה את הפתרון שלכם. +תוכן התוכנית לבחירתכם - תהיו יצירתיים. התוכנית לא תיבדק אוטומטית אלא רק בהצגה. -אין לשנות את הקבצים הנתונים, אלא רק להוסיף קבצים חדשים. +תוכלו לבדוק את הציון שלכם ע"י הפקודה: -יש לפתור את המטלה באופן עצמאי. +
-* מותר להתייעץ עם סטודנטים אחרים או לחפש מידע באינטרנט; -אסור להעתיק קטעי-קוד שלמים מסטודנטים אחרים או מהאינטרנט. -* יש לדווח על כל עזרה שקיבלתם, מסטודנטים אחרים או מהאינטרנט, בהתאם ל[תקנון היושר של המחלקה](https://www.ariel.ac.il/wp/cs/wp-content/uploads/sites/88/2020/08/Guidelines-for-Academic-Integrity.pdf). + bash grade
+ +
\ No newline at end of file diff --git a/Test.cpp b/Test.cpp index 3b7859a..c64b5d9 100644 --- a/Test.cpp +++ b/Test.cpp @@ -12,81 +12,77 @@ using namespace ariel; static vector units = {"m"}; ifstream units_file{"units.txt"}; -TEST_CASE("Multi operators"){ +TEST_CASE("km/m"){ NumberWithUnits::read_units(units_file); - NumberWithUnits a{1, "m"}; - NumberWithUnits b{3, "m"}; - NumberWithUnits c{300, "cm"}; - double num = 3; - CHECK(a*num==b); - CHECK(a*num==c); - CHECK(num*a==b); - CHECK(num*a==c); - double number = 2; - CHECK_FALSE(a*number==b); - CHECK_FALSE(a*number==c); - CHECK(number*a!=b); - CHECK(number*a!=c); + NumberWithUnits unit1{1, "km"}; + NumberWithUnits unit2{500, "m"}; + NumberWithUnits unitC1{1500, "m"}; + CHECK((unit2+unit1)==unitC1); + NumberWithUnits unitC2{1.5, "km"}; + CHECK((unit1+unit2)==unitC1); + CHECK((unit2+=unit1)==unitC1); + CHECK_FALSE((unit2+=unit1)==unitC2); + NumberWithUnits unitC3{-1.5, "km"}; + CHECK((unit1-unit2)==unitC3); + NumberWithUnits unitC4{1500, "m"}; + CHECK((unit2-unit1)==unitC4); + CHECK((unit2-unit1)!=unitC3); } +TEST_CASE("boolean"){ + NumberWithUnits unit1{101, "cm"}; + NumberWithUnits unit2{1, "m"}; + CHECK(unit1>unit2); + CHECK(unit1>=unit2); + CHECK(unit2<=unit1); + CHECK(unit2b); - CHECK(a>=b); - CHECK(b<=a); - CHECK(bc); - CHECK(d>=c); - CHECK(c>=e); - CHECK(e>=c); - CHECK(cunitB1); + CHECK(unitB2>=unitB1); + CHECK(unitB1>=unitB3); + CHECK(unitB3>=unitB1); + CHECK(unitB1= MIN_TESTS? run_stats.numAsserts: MIN_TESTS; + float grade = (run_stats.numAsserts - run_stats.numAssertsFailed) * 100 / numAsserts; + // std::cout << "Grade: " << grade << std::endl; + } +}; + +REGISTER_REPORTER("grader", /*priority=*/1, ReporterGrader); + +int main(int argc, char** argv) { + Context context; + context.addFilter("reporters", "grader"); + return context.run(); +} diff --git a/filename.txt b/filename.txt new file mode 100644 index 0000000..960c02f --- /dev/null +++ b/filename.txt @@ -0,0 +1,7 @@ +1 r_km = 1000 r_m +1 r_m = 100 r_cm +1 r_kg = 1000 r_g +1 r_ton = 1000 r_kg +1 r_hour = 60 r_min +1 r_min = 60 r_sec +1 r_USD = 3.33 r_ILS \ No newline at end of file diff --git a/filename2.txt b/filename2.txt new file mode 100644 index 0000000..f169d8e --- /dev/null +++ b/filename2.txt @@ -0,0 +1,4 @@ +1 r_school = 25 r_class +1 r_class = 25 r_student +1 r_EUR = 4 r_ILS +1 r_halfMin = 0.5 r_min \ No newline at end of file diff --git a/grade b/grade old mode 100755 new mode 100644 index 9f2d687..1edf536 --- a/grade +++ b/grade @@ -1,39 +1,54 @@ #!/bin/bash source grade_utils +TIMEOUT=10 run_in_folder_if_exists "$1" -printf "\n\n### Cleaning old files ###\n" -make -f Makefile clean +if [ -z "$DEBUG" ]; then + printf "\n\n### Cleaning old files (to prevent this, export DEBUG=1) ###\n" + make -f Makefile clean +fi total=0 i=0 let "i=i+1" -printf "\n\n### Check $i: our demo program should compile with your class\n" -grade_command make -j8 -f Makefile demo +printf "\n\n### Check $i: all tests should pass\n" +call make -f Makefile test1 +grade_command ./test1 printf "### Score $i: $grade\n" total=$((total + grade)) let "i=i+1" -printf "\n\n### Check $i: our demo program should run without errors\n" -grade_command ./demo +printf "\n\n### Check $i: all tests should pass\n" +call make -f Makefile test2 +grade_command ./test2 printf "### Score $i: $grade\n" total=$((total + grade)) let "i=i+1" -printf "\n\n### Check $i: your test should compile \n" -grade_command make -j8 -f Makefile test +printf "\n\n### Check $i: all tests should pass\n" +call make -f Makefile test3 +grade_command ./test3 printf "### Score $i: $grade\n" total=$((total + grade)) let "i=i+1" -printf "\n\n### Check $i: you should write some new tests\n" -grade_command ./test +printf "\n\n### Check $i: clang-tidy should run without warnings in user code\n" +grade_command make -f Makefile tidy printf "### Score $i: $grade\n" total=$((total + grade)) +let "i=i+1" +printf "\n\n### Check $i: valgrind should run without errors\n" +grade_command make -f Makefile valgrind +printf "### Score $i: $grade\n" +total=$((total + grade)) + + total=$((total / i)) printf "\n\nGrade: $total\n\n" -make -f Makefile --silent clean +# if [ -z "$DEBUG" ]; then +# make -f Makefile --silent clean +# fi diff --git a/grade_utils b/grade_utils index 065e0ac..8bed694 100644 --- a/grade_utils +++ b/grade_utils @@ -17,7 +17,7 @@ run_in_folder_if_exists() { cp $GRADEFILES $1/ call cd $1 source $0 - rm $GRADEFILES + # rm $GRADEFILES cd .. exit 0 fi diff --git a/graph.cpp b/graph.cpp new file mode 100644 index 0000000..24929df --- /dev/null +++ b/graph.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +class graph{ + protected: + map> the_graph; + set nodes; + map> edges_from; + + public: + bool checkExist(const string& node){ + return (nodes.count(node) > 0); + } + void addOut(const string &src, const string &dst){ + if (edges_from.count(src) > 0) + { + edges_from[src].insert(dst); + }else{ + set temp{dst}; + edges_from[src] = temp; + } + } + void addEdge(const string &src, const string &dst, double weight){ + addNode(src);addNode(dst); + the_graph[src][dst] = weight; + the_graph[dst][src] = ((double)1)/weight; + addOut(src,dst); + addOut(dst,src); + } + void addNode(const string &_node){ + nodes.insert(_node); + } + double getWeight(const string &src, const string &dst){ + if(the_graph[src][dst] <= 0){ + return -1; + } + return the_graph[src][dst]; + } + + // void print(std::list const &list) + // { + // for (auto const &i : list) + // { + // std::cout << i << " |-> "; + // } + // cout << endl; + // } + + double getConv(const string &src, const string &dst){ + stack s; + set visited; + map con; + s.push(src); + con[src] = 1; + while(!s.empty()){ + string cur = s.top(); + s.pop(); + if(visited.count(cur) < 1){ + visited.insert(cur); + if (cur == dst){ + return con[cur]; + } + for (string str : edges_from[cur]) + { + if (visited.count(str) < 1) + { + con[str] = getWeight(cur, str) * con[cur]; + s.push(str); + } + } + } + } + return -1; + } +}; + + + diff --git a/graph.hpp b/graph.hpp new file mode 100644 index 0000000..98dabe6 --- /dev/null +++ b/graph.hpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +class graph{ + protected: + map> _graph; + set _nodes; + map> _outEdges; + + public: + bool checkExist(const string& node); + void print(std::list const &list); + double getConv(const string &src, const string &dst); + set &_nodes(){} + map> &_graph(); + graph(map> graph, set nodes):_graph(graph), _nodes(nodes){}; + void addNode(const string &_node); + void addEdge(const string &src, const string &dst, double weight); + double getWeight(const string &src, const string &dst); + +}; + + + diff --git a/myTestFile.txt b/myTestFile.txt new file mode 100644 index 0000000..223eecc --- /dev/null +++ b/myTestFile.txt @@ -0,0 +1 @@ +1 USD = 3.33 ILS diff --git a/number-with-units-a.rar:Zone.Identifier b/number-with-units-a.rar:Zone.Identifier deleted file mode 100644 index 053d112..0000000 --- a/number-with-units-a.rar:Zone.Identifier +++ /dev/null @@ -1,3 +0,0 @@ -[ZoneTransfer] -ZoneId=3 -HostUrl=about:internet diff --git a/units.txt b/units.txt deleted file mode 100644 index d6312a6..0000000 --- a/units.txt +++ /dev/null @@ -1,7 +0,0 @@ -1 km = 1000 m -1 m = 100 cm -1 kg = 1000 g -1 ton = 1000 kg -1 hour = 60 min -1 min = 60 sec -1 USD = 3.33 ILS