CLIPS Python3 CLIPSError
Я столкнулся с небольшой проблемой с некоторым кодом CLIPSpy. Я сузил проблему до метода кодирования CLIPS_CONSTRUCTS.encode() или environment.load(constructs_file.name). Цель, которую я пытаюсь поймать, - запустить правило, когда температура масла выше 32, а давление масла выше 0. Я приложил файл SampleData.csv, с которым я работаю. Это часть моего дипломного исследования, и я хотел бы отдать должное всему, что выручило меня!
- ОС и версия: Windows 10 64-битная
- Версия Python: 3.7.2
- Библиотеки и версии (через список пунктов)
Cffi 1.11.5
Clipspy 0.3.0
Пип 18.1
pycparser 2.19
setuptools 40.6.2
import sys
from tempfile import NamedTemporaryFile
import clips
CLIPS_CONSTRUCTS = """
(deftemplate oil-measure
(slot utc-time (type STRING))
(slot temperature (type INTEGER))
(slot pressure (type INTEGER)))
(defrule oil-is-hot
(oil-measure (temperature ?temp) (utc-time ?time))
(test (> ?temp 32))
=>
(printout t ?time tab "temperature:" tab ?temp crlf))
(defrule pressure-is-high
(oil-measure (pressure ?press&:(> ?press 0)) (utc-time ?time))
=>
(printout t ?time tab "pressure:" tab ?press crlf))
"""
def main():
environment = clips.Environment()
# use environment.load() to load constructs from a file
with NamedTemporaryFile() as constructs_file:
constructs_file.write(CLIPS_CONSTRUCTS.encode())
constructs_file.flush()
environment.load(constructs_file.name)
# enable fact duplication as data has duplicates
environment.eval("(set-fact-duplication TRUE)")
# Template facts can be built from their deftemplate
oil_measure_template = environment.find_template("oil-measure")
for time, temp, press in get_data_frames(sys.argv[1]):
new_fact = oil_measure_template.new_fact()
# Template facts are represented as dictionaries
new_fact["utc-time"] = time
new_fact["temperature"] = int(temp)
new_fact["pressure"] = int(press)
# Add the fact into the environment Knowledge Base
new_fact.assertit()
# Fire all the rules which got activated
environment.run()
def get_data_frames(file_path):
"""Parse a CSV file returning the dataframes."""
with open(file_path) as data_file:
return [l.strip().split(",") for i, l in enumerate(data_file) if i > 1]
if __name__ == "__main__":
main()
2 ответа
Это ограничение NamedTemporaryFile
на Windows документировано здесь.
Вы можете обойти это используя mkstemp
или обычный файл, который вы удаляете сами, как только сделали.
constructs_file, constructs_file_name = mkstemp()
constructs_file.write(CLIPS_CONSTRUCTS.encode())
constructs_file.close()
environment.load(constructs_file_name)
os.remove(constructs_file_name)
Получил работу с помощью этого кода:
constructs_file, constructs_file_name = mkstemp()
file = open(constructs_file, 'wb')
file.write(CLIPS_CONSTRUCTS.encode())
file.close()
environment.load(constructs_file_name)
os.remove(constructs_file_name)
По какой-то причине в коде возникли проблемы с дескриптором файла, поскольку у него нет метода записи. Немного изменил код и бац! Оно работает!