Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[44.193.80.126] |
|
Сообщ.
#1
,
|
|
|
в вектор Vx и Vy считываю из файла вот такой ряд данных
01.2017 -525 02.2017 -571 03.2017 -363 04.2017 -384 05.2017 -537 06.2017 -671 но когда вывожу на экран Vx то получается только вот 2017 2017 2017 2017 кто-нибудь подскажет как исправить? vector<double>Vi; vector<double>Vj; double **massiv; massiv = new double*[count_row]; for (int i = 0; i < count_row; i++) { massiv[i] = new double[count_col]; } //считываем матрицу из файла for (int i = 0; i < count_row; i++) { for (int j = 0; j < count_col; j++) { massiv[i][j] = v.at(i*count_col + j); } } for (int i = 0; i < count_row; i++) { Vi.push_back(massiv[i][0]); Vj.push_back(massiv[i][1]); } for (auto it : Vx) { std::cout << it << std::endl; } Добавлено отпал вопрос |
Сообщ.
#2
,
|
|
|
Вот вам пример адекватного чтения файла в вашем формате.
#include <iostream> #include <string.h> #include <string> #include <sstream> #include <fstream> #include <memory> #include <vector> struct Time { int year; int month; }; class Row { private: double value; Time time; public: Row(Time time, double value); ~Row(); double getValue() const; Time getTime() const; }; typedef std::shared_ptr<Row> RowPtr; Row::~Row() { } Row::Row(Time time, double value){ this->time=time; this->value=value; } double Row::getValue() const { return this->value; } Time Row::getTime() const { return this->time; } namespace IOService { std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } std::vector<std::string> split(const std::string &s, char delim) { std::vector<std::string> elems; split(s, delim, elems); return elems; } std::vector<RowPtr> readData(std::string filename) { std::vector<RowPtr> result; std::ifstream file(filename); std::string line; while(std::getline(file, line)) { std::vector<std::string> items; try { items = split(line,' '); Time time; double value = std::stod(items[1]); std::vector<std::string> timeParams = split(items[0],'.'); time.year = std::stoi(timeParams[0]); time.month = std::stoi(timeParams[1]); result.push_back(RowPtr(new Row(time,value))); } catch (std::exception &e){ std::cout<<"exception: "<<e.what(); } } return result; } } void pause(){ int ret; std::cin>>ret; } int main() { std::vector<RowPtr> data = IOService::readData("test.txt"); for(std::vector<RowPtr>::iterator it = data.begin(); it!=data.end(); ++it){ Time time = (*it)->getTime(); double value = (*it)->getValue(); std::cout<<"time: "<<time.year<<"."<<time.month<<", value: "<<value<<"\n"; } pause(); return 0; } |
Сообщ.
#3
,
|
|
|
VisualProg, указатели (даже умные) тут совершенно не нужны и чтение данных можно организовать намного проще.
|
Сообщ.
#4
,
|
|
|
Цитата shm @ указатели (даже умные) тут совершенно не нужны Да, это уже вредная привычка, тут можно просто копировать вектора с содержимым при передачи. Цитата shm @ чтение данных можно организовать намного проще Ну, в отличие от ТС, эта часть кода у меня в листинге присутствует На то он и пример, что не заставляет делать только так а не иначе) |
Сообщ.
#5
,
|
|
|
Цитата VisualProg @ тут можно просто копировать вектора с содержимым при передачи. http://www.cplusplus.com/reference/vector/...r/emplace_back/ Добавлено https://habrahabr.ru/post/242639/ |
Сообщ.
#6
,
|
|
|
Цитата shm @ http://www.cplusplus.com/reference/vector/...r/emplace_back/ Добавлено 3 минуты назад https://habrahabr.ru/post/242639/ Великолепная статья и описание! Надо срочно к этому привыкать, огромное спасибо |
Сообщ.
#7
,
|
|
|
Цитата Nelly0892 @ но когда вывожу на экран Vx то получается только вот 2017 2017 2017 2017 а надо как? |
Сообщ.
#8
,
|
|
|
ты считать-то умеешь?
Цитата Nelly0892 @ 01.2017 -525 02.2017 -571 03.2017 -363 04.2017 -384 05.2017 -537 06.2017 -671 6 раз по 2017 должно быть, шесть! VisualProg, никогда не понимал это любви к нэймспесам, или каждый засвет std:: это минус 1мс к компиляции? почему бы просто не написать using namespace std, ы? да и не осилит неля такой код (только шаблонов не хватает), надо чёнить попроще. |
Сообщ.
#9
,
|
|
|
Цитата _lcf_ @ почему бы просто не написать using namespace std, ы? Ну для лабы пойдет. А вот в больших проектах бывают из-за конфликтов имен проблемы. |
Сообщ.
#10
,
|
|
|
Цитата _lcf_ @ никогда не понимал это любви к нэймспесам, или каждый засвет std:: это минус 1мс к компиляции? Это убирает вероятность пересечения имён. В шарпе и яве я этого избегаю потому что знаю окружение. А вот в плюсах и сях в глобальной области столько всего + всего этого я даже не знаю (а тут мы ещё и содержимое всяких std подтягиваем), поэтому боюсь на что нибудь нарваться Цитата _lcf_ @ надо чёнить попроще. Ну, тут суть не в самом коде, а в том что алгоритм чётко прослеживается - идёт загрузка, что происходит по время чтения видно не вооружённым глазом - обычные split-ы и преобразования из строки в int/double. А так, да, можно убрать класс и всё в структуру впихнуть, но, тогда всё начнёт копироваться по значению... |
Сообщ.
#11
,
|
|
|
ну это совсем фантазии не должно быть, чтобы законфликтовать со стандартными нэймспейсами. да и решение простое есть - префиксы, в соответствии с проектом/модулем. в любом случае это проще, чем писать по стопицот раз имя пространства. да и юзинг не обязательно на весь сипишник кидать
|
Сообщ.
#12
,
|
|
|
Цитата _lcf_ @ ну это совсем фантазии не должно быть, чтобы законфликтовать со стандартными нэймспейсами. Законфликтовать могут и внешние либы, причем ситуация встречается довольно часто. |
Сообщ.
#13
,
|
|
|
я не делаю юзинг только если упоминаний мало или когда в одном месте явно разные сущности перескаются, например std и opencv, и то не для того, чтобы конфликтов не было, а чтобы видеть где чьё
|
Сообщ.
#14
,
|
|
|
И на мой взгляд пространства имен - это более элегантное решение, чем префиксы в названиях.
|
Сообщ.
#15
,
|
|
|
Цитата shm @ И на мой взгляд пространства имен - это более элегантное решение, чем префиксы в названиях. Именно! А в некоторых крупных проектах запрещено использовать префиксы, особенно если код не связан с низкоуровневым программированием. |
Сообщ.
#16
,
|
|
|
Цитата shm @ Законфликтовать могут и внешние либы, причем ситуация встречается довольно часто. в одной функции встречаеются функции с одинаковым названием из разных либ? и такое часто случается? Добавлено Цитата shm @ И на мой взгляд пространства имен - это более элегантное решение угу, но только либо это имя короткое и неговорящее, либо строчки кода за экран уезжают |
Сообщ.
#17
,
|
|
|
Да и через std:: быстрее набрать тип через подсказку, чем вспоминать как он там пишется uniqe или uniqueue или unique, если конечно не в блокноте пишешь.
|
Сообщ.
#18
,
|
|
|
киля, надо поменьше дыва дуть, тогда и запомнишь
ладно, я тоже стд не подключаю, но потому что мало его юзаю. а что часто юзаю, особенно свои неймспейсы - то подключаю |
Сообщ.
#19
,
|
|
|
Цитата KILLER @ через std:: быстрее набрать тип через подсказку + удобно искать соответствующие "ветки" пространств имён, вот пример из реального проекта: #pragma once #include "../servlets.h" #include "../../DB/dao/SpecificDAO.hpp" #include "../../DB/dao/GuestsDAO.hpp" #include "../../Model/GuestDTO.hpp" namespace Servlets { class get_guests : public Servlet { public: get_guests() : Servlet("/get_guests", DBO::ADMIN) { } void doGet (HttpRequest *request, HttpResponse *response) { } void doPost(HttpRequest *request, HttpResponse *response) { unsigned int count = request->getIntParameter("count"); unsigned int offset = request->getIntParameter("offset"); if(count>100){ count=100; } Properties filters = request->getPrpParameter("filters"); DBO::DTOList guests; guests = DAO::GuestDAO::getGuests(&filters,offset,count); // получаем всех гостей из базы данных std::string data = HTTP::Service::JSON::create(guests,"data"); // преобразуем список гостей в json объект out<<data; // отправляем json данные } }; } В подпространствах DAO - видны все сервисы под разные базы данных и таблицы, в конкретном сервисе видны все функции связанные именно с этой таблицей или сущностью. В общем, это реально упрощает жизнь. |
Сообщ.
#20
,
|
|
|
Цитата _lcf_ @ киля, надо поменьше дыва дуть, тогда и запомнишь А дыво то тут причем? Ты мне сходу скажешь сейчас как называется класс для работы с строковыми потоками и в каком хидере это находится? Когда ты часто что то используешь - оно у тебя откладывается в подсознании и ты пишешь это все на автомате. А когда ты раз в год какую то вещь используешь, то хоть дуешь ты дыво, хоть не дуешь - хрен ты запомнишь. Так вот хорошим тоном, как выше сказали, правильно не открывать все пространство имен, а использовать только то, что тебе нужно. Если лень писать каждый раз std:: то можно написать например: using std::cout; И использовать его. Хотя у меня уже на автомате пишется std:: и никак это не напрягает. |
Сообщ.
#21
,
|
|
|
Любое явное лучше, чем неявное. Чёткое указание используемого интерфейса делает хорошо всем, и компилятору в последнюю очередь.
|
Сообщ.
#22
,
|
|
|
ну еще скажите this-> пишете? (конструкторы, операторы не в счёт)
|
Сообщ.
#23
,
|
|
|
Цитата _lcf_ @ ну еще скажите this-> пишете? (конструкторы, операторы не в счёт) Если слишком много наследования, сложные классы и куча всего, да еще и не ты это все писал, то почему бы и нет? А как ты ищешь? Пол часа лазаешь по всем классам и наследованию, или поиском ищешь? Добавлено Другое дело, что после того как нашел нужный метод, this-> можно и удалить, для гармонии. |
Сообщ.
#24
,
|
|
|
Цитата KILLER @ А как ты ищешь? ну обычно я с другой стороны прихожу - usages |
Сообщ.
#25
,
|
|
|
Цитата _lcf_ @ ну еще скажите this-> пишете? Естественно Даже там где это не требуется, просто потому что сразу видно что это не переменная взятая откуда-то, а поле текущего экземпляра. Короче, _lcf_, как писать - дело твоё, но, смысл всех этих договорённостей можно понять только на практике, когда у тебя огромный проект, который живёт уже больше 5 лет, и ты должен его активно поддерживать, дополнять и изменять, без всего этого никто тебе ничего доказать не сможет, потому что ты не видишь реального преимущества такого подхода |
Сообщ.
#26
,
|
|
|
хм, ну наш проект собирается 9 минут на 40ядерном ксеоне + 128Гб. и ему не 5 лет. последнее время одну глобальную штуку правлю, комиты - изменения в 70-80 файлах, и что-то я, блин, не вижу там обилия :: как и не страдаю от отсутствия каких-то подсказок. интерфейс класса - вот он, иерархия - вот она, использование - вот оно. скорее проблемы со всякими моделями - где, что, как и почему меняется, но это никак с пространством имен не связано
Цитата VisualProg @ просто потому что сразу видно что это не переменная взятая откуда-то, а поле текущего экземпляра. ну почти в любом коде-стайле есть какое-то соглашение на этот счёт, у нас стандартное m_ да, и чистых сей у нас не так много, кутэ + куча своих враперов. |
Сообщ.
#27
,
|
|
|
Цитата _lcf_ @ Без надобности нет, все элементы класса уже в текущей области видимости. Та же ситуация, что и с пространствами имён, впрочем. Если бы ты был внимательнее, то заметил б прошлом посте к существительному "интерфейс" прилагательное "используемый".ну еще скажите this-> пишете? Та же getline() в коде выше – вот что за getline() заюзал VisualProg в своём примере, если б не std:: перед ней? Ещё какая-то функция, которую он забыл расположить рядом со split()? Конечно, using бывают полезны и могут использоваться в ряде случаев, но не везде направо и налево. В локальной области видимости некой функции, например, вполне, т.к. используемые ею интерфейсы обычно известны. Глобальные же они только мешают. Если уж сильно напрягает длинная явная квалификация, лучше вместо using использовать namespace = . |
Сообщ.
#28
,
|
|
|
Цитата Qraizer @ Глобальные же они только мешают. а глобально это как? кто-то в хидерах юзинг пишет? или сипишники по стопицот строчек? ну не должно быть объективных причин писать что-нибудь типа: std::chrono::high_resolution_clock::now(); да еще и цать раз в пределах одной функции. хотя, я думаю мы просто про разные вещи говорим, но глядя на код VisualProg, using на всю харю напрашивается |
Сообщ.
#29
,
|
|
|
Цитата _lcf_ @ ну не должно быть объективных причин писать что-нибудь типа: std::chrono::high_resolution_clock::now(); да еще и цать раз в пределах одной функции. хотя, я думаю мы просто про разные вещи говорим, но глядя на код VisualProg, using на всю харю напрашивается Для меня предпочтительней именно такая запись, особенно если нужно ее вызвать не более 2-3 раз. А если тебе нужно писать такое 100500 раз(что крайне сомнительно), тогда можешь просто укоротить неймспейс как тебе Qraizer выше написал, аля: namespace my_space = std::chrono::high_resolution_clock; |
Сообщ.
#30
,
|
|
|
помоему это паранойя вспомнился анекдот про еврея, десять замков и цепочку. может оно, конечно, и правильно, но как по мне так избыточно.
вот с точки зрения компиля аргумент интересный, но я в этом не силен. типо явное указание пространства как-то ускоряет парсинг, сокращает время сборки или что? |
Сообщ.
#31
,
|
|
|
Цитата _lcf_ @ ну почти в любом коде-стайле есть какое-то соглашение на этот счёт, у нас стандартное m_ да, и чистых сей у нас не так много, кутэ + куча своих враперов. Повторюсь, у нас нельзя использовать префиксы, в любом виде. У нас любой префикс - признак низкоуровневой библиотеки, а в таких библиотеках свои наборы соглашений. Цитата _lcf_ @ и что-то я, блин, не вижу там обилия :: как и не страдаю от отсутствия каких-то подсказок Это скорее исключение из правил. Твои слова можно легко подтвердить или опровергнуть, для этого достаточно посадить за ваши исходники нового программиста, и посмотреть как он будет осваиваться в этом проекте. По его реакции и можно судить о том есть ли реальные страдания в процессе программирования или нет) |
Сообщ.
#32
,
|
|
|
Цитата VisualProg @ для этого достаточно посадить за ваши исходники нового программиста, и посмотреть как он будет осваиваться в этом проекте ну я кагбэ 4 месяца тут работаю |
Сообщ.
#33
,
|
|
|
Цитата _lcf_ @ ну я кагбэ 4 месяца тут работаю Если у тебя нет ни к чему притензий, значит проект действительно хорошо спроектирован. У меня же по чужим исходникам могут возникать различные вопросы, особенно когда под рукой нет полноценной IDE. Значит я просто не имею такого опыта в разработке как у тебя) |
Сообщ.
#34
,
|
|
|
Цитата _lcf_ @ помоему это паранойя вспомнился анекдот про еврея, десять замков и цепочку. может оно, конечно, и правильно, но как по мне так избыточно. Это не паранойя, это здравый смысл, потому как потом, когда ты откроешь незнакомый тебе код и увидишь что то типа: SomeMethod(...) { auto t = now(); ... return t; } То будешь долго морщить лоб, и гадать - ээээ, а что такое now, и какого это все типа, и откуда это все взялось. Т.е. когда ты вот так открываешь неймспейсы, ты сразу в несколько раз ухудшаешь читабельность кода. Цитата _lcf_ @ вот с точки зрения компиля аргумент интересный, но я в этом не силен. типо явное указание пространства как-то ускоряет парсинг, сокращает время сборки или что? Скорее просто компилятор отбросит весь мусор, который не подключен через пространство имен. А если подключит, то может не отбросит, ну и когда ты пишешь явно пространство имен, ты избегаешь колизий. Плюс читабельность кода возрастает в несколько раз. Вот например во многих конторах любят переписать работу со строками/потоками под себя, или еще с чем то, а потом ты сидишь и думаешь стандартный это класс или свой внутренний. Ясно что стандартный вроде, но иногда это здорово запутывает. А когда явно пишешь std::string, то сразу видно откуда он взятый. |
Сообщ.
#35
,
|
|
|
Цитата KILLER @ Вот например во многих конторах любят переписать работу со строками/потоками под себя, или еще с чем то, а потом ты сидишь и думаешь стандартный это класс или свой внутренний. Ясно что стандартный вроде, но иногда это здорово запутывает. А когда явно пишешь std::string, то сразу видно откуда он взятый. Или стандартные коллекции со своими thread-safe плюшками |
Сообщ.
#36
,
|
|
|
Цитата VisualProg @ Если у тебя нет ни к чему притензий, значит проект действительно хорошо спроектирован. я не говорил, что претензий нет вообще, я говорил за неймспейсы Цитата VisualProg @ У меня же по чужим исходникам могут возникать различные вопросы, ну и опять же когда совсем туго есть тимлид. Цитата KILLER @ когда ты откроешь незнакомый тебе код и увидишь что то типа: Цитата KILLER @ То будешь долго морщить лоб, и гадать - ээээ, а что такое now эм, ну такое сплошь и рядом, ctrl+клик - в чём проблема? ну а переписывать стандартные функции с тем же именем - это первая глупость. вторая - использовать их без явного указания пространства. |
Сообщ.
#37
,
|
|
|
Цитата _lcf_ @ эм, ну такое сплошь и рядом, ctrl+клик - в чём проблема? Ну выдаст тебе 4-5 разных реализаций now с разных библиотек, включая стандартную, какую нибудь бустовскую, еще какую нибудь внутрению и еще парочку с каких нибудь ATL/MFC, и сиди думай - какая из них вызовется. Да, может ты догадаешься какая из найденных используется в твоем случае, но и время потеряешь. А если у тебя будет сразу указано откуда это взялось - тебе достаточно посмотреть на эту написанную строку, и не нужно ничего гадать и искать. |
Сообщ.
#38
,
|
|
|
какой заяц, какой орёл, какая блоха!? (С)
вот не бывает у меня таких ситуаций почему-то, ну или я их не запоминаю... почему-то мне кажется, что если такая ситуация возникла, то надо давать пинка лентяйм-любителям auto, чтобы явно писали, что они вызывают. Добавлено и чем, кстати, запись: auto d = blabla::some::get_iterator (); будет отличаться от: blabla::some::iterator d = get_iterator (); |
Сообщ.
#39
,
|
|
|
Цитата _lcf_ @ почему-то мне кажется, что если такая ситуация возникла, то надо давать пинка лентяйм-любителям auto, чтобы явно писали, что они вызывают. ну или любителям открывать неймспейсы Добавлено Цитата _lcf_ @ и чем, кстати, запись: У Майерса написано что auto предпочтительнее, так как тип данных задает компилятор и он будет максимально соответствовать тому, что ты присваиваешь. А сам ты можешь написать так, а например iterator() у тебя возвращает какой нибудь константный объект. Или например как любят писать некоторые: std::vector<int> vint; vint.push_back(1); for( int idx = 0; idx < vint.size(); ++idx) { ... } Вот тут уже будет трабла, варнинг какой нибудь, а если ты напишешь так: std::vector<int> vint; vint.push_back(1); for( auto idx = 0; idx < vint.size(); ++idx) { ... } То траблы не будет. В первом случае у тебя небезопасное преобразование из size_t(который unsigned int) в int, во втором случае все ок, idx будет типа size_t. Ну и сокращает написание вот этих вот blabla::some::iterator d до 4 букв. |
Сообщ.
#40
,
|
|
|
Цитата KILLER @ Вот тут уже будет трабла, варнинг какой нибудь, фиксить надо. весьма рад, что на новой работе ворнинги запрещены. заелся на старой среди туевой хучи ворнингов искать еррор из-за которого не компилиться. причем ворнинги как раз похожие и были: compare signed/unsigned, unused parameter... Цитата KILLER @ Ну и сокращает написание вот этих вот blabla::some::iterator d до 4 букв. ничего не сокращается, просто из левой части в правую переезжает. |
Сообщ.
#41
,
|
|
|
Цитата _lcf_ @ ничего не сокращается, просто из левой части в правую переезжает. В каком смысле из левой в правую переезжает? В правой части оно всегда почти есть, а в левой тебе или тип придется писать или auto или извращаться со всякими typedef'ами. Например вот есть вот такой код: std::map<std::string, std::vector<std::string>> GetCategories(const std::string& CatId) { } int main() { auto categories = GetCategories(CatId); for(auto It = categories.begin(); It != categories.end(); ++It) {... } } Попробуй переписать без auto. Добавлено Ну и самое наверное хорошее что несет в себе auto, это то, что если вдруг изменится тип, то по сути ничего переписывать не придется, ну если он конечно не кардинально изменился. |
Сообщ.
#42
,
|
|
|
киля, дыва таки даёт о себе знать
Цитата KILLER @ Ну выдаст тебе 4-5 разных реализаций now с разных библиотек, где в твоем куске кода какие-либо неймспейсы из которого вылазит GetCategories Добавлено против auto я ничего не имею, кроме случаев, когда он порождает неоднозначность. |
Сообщ.
#43
,
|
|
|
Цитата _lcf_ @ где в твоем куске кода какие-либо неймспейсы из которого вылазит GetCategories Ты тоже чтоль дыва пыхнул? Ты перечитай о чем идет речь. Смотри ты пишешь чем отличается написание: auto iterator = lala от trololo::lolo::bugaga iterator = lala; Я тебе пишу тем то и тем то, плюс ко всем не нужно писать огород из всех этих trololo::lolo::bugaga, достаточно написать 4 буквы. Ты мне в ответ написал что ниче там не сокращается, а " просто из левой части в правую переезжает. " Я твоего ответа не понял, переспросил что ты имеешь ввиду и привел тебе пример. Причем тут вложенные неймспейсы? Добавлено при работе с итераторами в STL, основная проблема в ненаписании вложенных неймспейсов типа там std::chrono, основная проблема написать вот такие вот конструкции как выше, аля: std::map<std::string, std::vector<std::string>>::const_iterator мать его. Тут ты уже ниче не откроешь чтоб сократить запись до пары символов, тут придется или auto писать или какой нибудь typedef. Добавлено Я могу понять, когда некоторые называют свои пространства имен как хз кто, типа там: namespace This_is_my_mega_super_puper_namespace {} Тогда да, задолбаешься такое набирать на каждой строчке. А когда неймспейс состоит из 2-4 символов, это только помогает быстро писать, с помощью того же автокомплитера и подсказок. Особенно когда у тебя куча всяких неймспейсов, а как там называется класс ты не помнишь, но помнишь первые несколько букв или даже слово. |
Сообщ.
#44
,
|
|
|
Цитата KILLER @ Смотри ты пишешь чем отличается написание: auto iterator = lala от trololo::lolo::bugaga iterator = lala; начинай сначала... Цитата KILLER @ auto t = now(); Цитата KILLER @ Ну выдаст тебе 4-5 разных реализаций now с разных библиотек то есть, подразумевалось, что надо написать: auto t = some::foo::bar::now () так? тогда я и спрашиваю, а чем, собсено, эта запись отличается от: some::foo::bar::value_of_now t = now (); |
Сообщ.
#45
,
|
|
|
Тем, что во втором случае ты с лева почемуто написал всю цепочку неймспейсов, а now вызвал почему то без перечисления неймспейсов. А вообще выше я вроде ответил уже.
|
Сообщ.
#46
,
|
|
|
Цитата _lcf_ @ Вот уж кому на это дело плевать с высокой колокольни. Разговор именно про восприятие и понимание текста человеком. вот с точки зрения компиля аргумент интересный, ... Добавлено Цитата _lcf_ @ Надо, чтобы они на всех работах были запрещены. Эх... весьма рад, что на новой работе ворнинги запрещены. |
Сообщ.
#47
,
|
|
|
Цитата Qraizer @ Надо, чтобы они на всех работах были запрещены. Эх... На некоторых работах их даже не включают. А некоторые даже не знают про их существование. |