Как можно синхронизировать C++ и Python
Всем привет! Столкнулся с такой необходимостью, у меня есть код, написанный на C++ это программа со статистикой(там диаграмма и графики). И есть код на Python, который использует нейросеть для определения эмоций(tensorflow и opencv). Можно ли что-то сделать чтобы они работали вместе, то есть python работал в фоне и экспортировал статистику в C++. Я бы смог написать это все вместе. Но не получается найти скомпилированную библиотеку tensorflow для C++(для её компиляции требуется 12 ГБ ОЗУ, у меня только 8).
Отслеживать
задан 14 мая 2018 в 18:06
129 7 7 бронзовых знаков
Посмотрите, например, на передачу данных по пайпу
14 мая 2018 в 18:29
@avp, а как это можно реализовать? Если есть возможность скиньте какой-нибудь гайд на русском. В гугле информации про это мало. Я в python’е не силен.
14 мая 2018 в 18:33
Гайдов не помню. Поищите примеры с fork/dup/exec, в которых stdin/stdout нового процесса переключаются на пару пайпов (man pipe) Т.о. python запускаете в дочернем процессе, он читает stdin и пишет ответы в stdout
14 мая 2018 в 18:39
существует множество способов связать питон и c++ код (помимо обычных IPC методов)¶ Мы живём в интересные времена, если люди могут tensorflow использовать, но не знают как связать две команды с помощью pipe¶ Если C++ заметную работу вычислительную выполняет, то из Питона можно вызовы делать, если нет, то графопостроительством может быть удобней из Питона заниматься. Как с помощью python сделать модуль для c++
14 мая 2018 в 20:24
@avp Это не будет компилироваться на винде же. Cygwin такое вроде и умеет, но это частный случай. Поэтому лучше уже юзать сокеты, ибо для сокетов можно найти какую-нибудь кроссплатформенную либу
Python: Конкатенация
В веб-разработке программы постоянно оперируют строками. Все, что мы видим на сайтах, так или иначе представлено в виде текста. Этот текст чаще всего динамический — то есть он получается из разных частей, которые соединяются вместе.
Чтобы соединить строки, нужно выполнить конкатенацию:
# Оператор такой же, как и при сложении чисел, # но здесь он имеет другой смысл (семантику) print('Dragon' + 'stone') # => Dragonstone
Склеивание строк всегда происходит в том же порядке, в котором записаны операнды. Левый операнд становится левой частью строки, а правый — правой. Вот еще несколько примеров:
print('Kings' + 'wood') # => Kingswood print('Kings' + 'road') # => Kingsroad print("King's" + 'Landing') # => King'sLanding
Как видите, строки можно склеивать, даже если их записали с разными кавычками.
Пробел — такой же символ, как и другие, поэтому сколько пробелов поставите в строке, столько и получится в итоговой строке:
# Ставим пробел в левой части print("King's " + 'Landing') # => King's Landing # Ставим пробел в правой части print("King's" + ' Landing') # => King's Landing
Задание
Выведите на экран
Winter came for the House of Frey.
используя конкатенацию слов.
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Полезное
- Если в редакторе есть запись # BEGIN и # END , то код нужно писать между этими строчками.
Определения
- Конкатенация — операция соединения двух строк. Например, print(«King’s » + ‘ Landing’)
Интеграция Python и C++
Недавно при прототипировании одной из частей разрабатываемого нами продукта возникла одна интересная задача: нужно было проверить склейку Python и C++. Связано это было с тем, что основной код был написан на плюсах, и необходимо было подключить внешнюю библиотеку Websockets, написанную на Python (на тот момент не было соответствующей библиотеки на C++). Схема взаимодействия при такой задаче достаточно простая. Из C++ вызывается функция подключения к серверу (на python), в качестве параметра передается его адрес. Соответственно, при получении сообщния Python передавает его обратно в метод C++.
При написании кода использовалась питоновская библиотека Websocket от Autobahn (http://www.tavendo.de/autobahn/clientlibraries.html), которую было необходимо вызывать из C++. Для этих целей в Python предусмотрен Python C-API (http://docs.python.org/extending/index.html), однако многие простые действия, например, вызов функций делается несколькими действиями. После небольшого гугления был найден ряд библиотек, позволяющих упростить подобные действия: Boost.Python (http://www.boost.org/doc/libs/1_39_0/libs/python/doc/index.html), SWIG(http://www.swig.org/), Py++, Pybindgen, Pyrex… В результате был выбран Boost.Python как наиболее популярное решение.
Для начала напишем простенький эхо клиент на Python, который будет раз в секунду посылать сам себе сообщение “Hello world”, принимать его и отдавать в C++. cppMethods будет объявлен в C++ коде, cppMethods.printMessage(msg) — как раз место склейки со стороны Python, непосредственно вызов функции C++, которая будет печатать полученное сообщение.
Вот код Python — echo-client.py:
from twisted.internet import reactor from autobahn.websocket import WebSocketClientFactory, WebSocketClientProtocol, connectWS import cppMethods class EchoClientProtocol(WebSocketClientProtocol): def sendHello(self): self.sendMessage("Hello, world!") def onOpen(self): self.sendHello() def onMessage(self, msg, binary): cppMethods.printMessage(msg) reactor.callLater(1, self.sendHello) def Connect(addressStr): factory = WebSocketClientFactory(addressStr) factory.protocol = EchoClientProtocol connectWS(factory) reactor.run()
Теперь напишем на C++ код, в котором опишем нашу функцию, вызываемую из питона. Для использования Python C-API нужно проинклудить Python.h. Обратите внимание, что на этом этапе мы еще не используем Boost.Python, лишь собственно родной Python C-API.
#include #include #include static PyObject * printString(PyObject * self, PyObject* args) < const char * toPrint; if(!PyArg_ParseTuple(args, "s", &toPrint)) < return NULL; >std::cout static PyMethodDef EmbMethods[] = < , >;
В последнем объявлении мы описали, что при вызове функции printMessage из Python будет вызван C++ метод printString.
Ну и наконец свяжем все это вместе. Для проверки работы websockets, помимо эхо-клиента, была использована ссылка на html5labs.
WebSocketConnect.cpp:
#include #include #include #include #include "PrintEmb.cpp" void WebSocketConnect() < using namespace boost::python; Py_Initialize(); Py_InitModule("cppMethods", EmbMethods); PyObject * ws = PyImport_ImportModule("echo_client"); std::string address = "ws://html5labs-interop.cloudapp.net:4502/chat"; call_method(ws, "Connect", address); Py_Finalize(); >
В этом месте мы все-таки воспользовались возможностями Boost, а именно функцией call_method, иначе бы нам понадобилось написать существенно больше кода.
Ну вот как-то так. Здесь мы поинициализировали EmbMethods для питона, назвав их cppMethods, а затем вызвали из Python метод Connect и передали в него строку “address”. В результате наше приложение раз в секунду печатает строку «Hello World» (которую посылает сам себе питон), а также любое сообщение, приходящее с сервера вебсокетов.
Вот таким образом можно связать Python и C++. Буду благодарен за комментарии по теме.
Upd. Поправил код в соответствии с замечаниями из комментариев.
Как объединить списки в Python
В этом руководстве мы представим различные методы объединения списков в Python. Списки служат для хранения однородных элементов и выполнения над ними манипуляций.
В общем, конкатенация – это процесс соединения элементов определенной структуры данных сквозным способом.
Ниже приведены 6 способов объединения списков в Python.
- оператор конкатенации (+);
- метод Naive;
- List Comprehension;
- метод extension()
- оператор ‘*’;
- метод itertools.chain().
1. Оператор (+) для конкатенации списков
Оператор «+» можно использовать для объединения двух списков. Он добавляет один список в конец другого списка и дает новый список в качестве вывода.
list1 = [10, 11, 12, 13, 14] list2 = [20, 30, 42] res = list1 + list2 print ("Concatenated list:\n" + str(res))
Concatenated list: [10, 11, 12, 13, 14, 20, 30, 42]
2. Метод Naive
В методе Naive цикл for используется для обхода второго списка. После этого элементы из второго списка добавляются к первому списку. Первый список является объединением первого и второго списков.
list1 = [10, 11, 12, 13, 14] list2 = [20, 30, 42] print("List1 before Concatenation:\n" + str(list1)) for x in list2 : list1.append(x) print ("Concatenated list i.e. list1 after concatenation:\n" + str(list1))
List1 before Concatenation: [10, 11, 12, 13, 14] Concatenated list i.e. list1 after concatenation: [10, 11, 12, 13, 14, 20, 30, 42]
3. Concatenated list для объединения списков
Concatenated list в Python – это альтернативный метод объединения двух списков в Python. Понимание списка – это в основном процесс построения и генерации списка элементов на основе существующего списка.
Он использует цикл for для обработки и обхода списка поэлементно. Приведенный ниже встроенный цикл for эквивалентен вложенному циклу for.
list1 = [10, 11, 12, 13, 14] list2 = [20, 30, 42] res = [j for i in [list1, list2] for j in i] print ("Concatenated list:\n"+ str(res))
Concatenated list: [10, 11, 12, 13, 14, 20, 30, 42]
4. Метод extend()
Метод extend() можно использовать для объединения двух списков в Python. Функция extend() выполняет итерацию по переданному параметру и добавляет элемент в список, тем самым расширяя список линейным образом.
list.extend(iterable)
list1 = [10, 11, 12, 13, 14] list2 = [20, 30, 42] print("list1 before concatenation:\n" + str(list1)) list1.extend(list2) print ("Concatenated list i.e ,ist1 after concatenation:\n"+ str(list1))
Все элементы list2 добавляются к list1, и, таким образом, list1 обновляется и выводится.
list1 before concatenation: [10, 11, 12, 13, 14] Concatenated list i.e ,ist1 after concatenation: [10, 11, 12, 13, 14, 20, 30, 42]
5. Оператор ‘*’
Оператор Python ‘*’ можно использовать для простого объединения двух списков. Оператор ‘*’ в Python в основном распаковывает коллекцию элементов по аргументам индекса.
Например: рассмотрим список my_list = [1, 2, 3, 4].
Оператор * my_list заменит список его элементами в позициях индекса. Таким образом, он распаковывает элементы списков.
list1 = [10, 11, 12, 13, 14] list2 = [20, 30, 42] res = [*list1, *list2] print ("Concatenated list:\n " + str(res))
В приведенном выше фрагменте кода инструкция res = [* list1, * list2] заменяет list1 и list2 элементами в заданном порядке, то есть элементами list1 после элементов list2. Это выполняет конкатенацию и приводит к выводу ниже.
Concatenated list: [10, 11, 12, 13, 14, 20, 30, 42]
6. Метод Python itertools.chain()
Функция itertools.chain() модулей itertools также может использоваться для объединения списков в Python. Функция принимает в качестве параметров различные итерации, такие как списки, строки, кортежи и т.д., и выдает их последовательность в качестве вывода.
В результате получается линейная последовательность. Тип данных элементов не влияет на работу метода chain().
Например: инструкция itertools.chain ([1, 2], [‘John’, ‘Bunny’]) выдаст следующий результат: 1 2 John Bunny
import itertools list1 = [10, 11, 12, 13, 14] list2 = [20, 30, 42] res = list(itertools.chain(list1, list2)) print ("Concatenated list:\n " + str(res))
Concatenated list: [10, 11, 12, 13, 14, 20, 30, 42]