LINUX.ORG.RU

Зацените пример написания программы с помощью нейросетки.

 ,


0

5

Поигрался с локальной нейросеткой, ориентированной специально на написание программ. https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct (в примере использования число выходных токенов увеличил до 1024)

Решил дать ей некую реальную задачу и посмотреть что из этого выйдет. Например, как она напишет конвертер для e-book из формата FB2 в plain text. По умолчанию результат выдаётся на питоне.

Недолго думая, задал ей промпт: «Write a converter from FB2 e-book format to plain text» Результат:

import sys
import re
from lxml import etree

def fb2_to_text(fb2_file):
    # Parse the FB2 file
    tree = etree.parse(fb2_file)
            
    # Find all text elements within <p> tags
    paragraphs = tree.xpath('//p/text()')
        
    # Combine all paragraphs into a single string
    text = ' '.join(paragraphs)
    
    # Remove any unwanted characters or formatting
    cleaned_text = re.sub(r'\n+', '\n', text.strip())
    cleaned_text = re.sub(r'\s+', ' ', cleaned_text)
    
    return cleaned_text

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python fb2_to_txt.py <path_to_fb2_file>")
        sys.exit(1)
    
    fb2_file = sys.argv[1]
    txt_content = fb2_to_text(fb2_file)
    
    # Write the text content to a new file
    txt_file = fb2_file.replace('.fb2', '.txt')
    with open(txt_file, 'w', encoding='utf-8') as f:
        f.write(txt_content)
    
    print(f"Converted {fb2_file} to {txt_file}")

Результат удивительный, вот только после работы скрипта на выходе пустой файл. Хммммм. Не сразу даже вспомнил, что вообще-то в XML бывают пространства имён и xpath их должен учитывать.

Новый промпт: «Write a converter from FB2 e-book format to plain text, using correct xpath for xmlns»

Выдало:

import sys
from lxml import etree

def fb2_to_text(fb2_file):
    # Parse the FB2 file
    tree = etree.parse(fb2_file)
    root = tree.getroot()

    # Define the namespace
    nsmap = {'fb2': 'http://www.gribuser.ru/xml/fictionbook/2.0'}

    # Extract the title of the book
    title = root.xpath('//fb2:book-title//fb2:title', namespaces=nsmap)[0].text.strip()

    # Extract all paragraphs and join them into plain text
    paragraphs = root.xpath('//fb2:p/text()', namespaces=nsmap)
    text_content = '\n'.join(paragraphs).strip()

    return text_content

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python fb2_to_txt.py <path_to_fb2_file>")
        sys.exit(1)

    fb2_file = sys.argv[1]
    text_content = fb2_to_text(fb2_file)
    print(text_content)

С одной стороны лучше, но пропала запись в файл (хотя это спорно нужна ли она) и вообще скрипт при работе сваливается с ошибкой индексации на строчке title = root.xpath('//fb2:book-title//fb2:title', namespaces=nsmap)[0].text.strip()

А тут я даже не сразу сообразил в чём дело. Но для множественного выбора тегов нужно добавить вертикальную черту, т.е, должно быть

title = root.xpath('//fb2:book-title | //fb2:title', namespaces=nsmap)[0].text.strip()

Правда, отдельный вывод title и вовсе сомнительной нужности. Ну то есть, для не совсем тривиального конвертера он конечно нужен, чтобы красиво вывелся заголовок, были учтены и другие элементы оформления, но для простенького примера наверное оно лишнее. В итоге, в 1-й вариант вручную перенёс только работу с xmlns. В итоге получилось

import sys
import re
from lxml import etree

def fb2_to_text(fb2_file):
    # Parse the FB2 file
    tree = etree.parse(fb2_file)
    
    # Define the namespace
    nsmap = {'fb2': 'http://www.gribuser.ru/xml/fictionbook/2.0'}
        
    # Find all text elements within <p> tags
    paragraphs = tree.xpath('//fb2:p/text()',namespaces = nsmap)
   
    
    # Combine all paragraphs into a single string
    text = ' '.join(paragraphs)
    
    # Remove any unwanted characters or formatting
    cleaned_text = re.sub(r'\n+', '\n', text.strip())
    cleaned_text = re.sub(r'\s+', ' ', cleaned_text)
    
    return cleaned_text

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python fb2_to_txt.py <path_to_fb2_file>")
        sys.exit(1)
    
    fb2_file = sys.argv[1]
    txt_content = fb2_to_text(fb2_file)
    
    # Write the text content to a new file
    txt_file = fb2_file.replace('.fb2', '.txt')
    with open(txt_file, 'w', encoding='utf-8') as f:
        f.write(txt_content)
    
    print(f"Converted {fb2_file} to {txt_file}")

И оно работает! Простейший конвертер таки написан! Не могу сказать, что целиком нейросеткой, но у неё почти получилось. Может быть, если поупражняться с промптами, получится и вовсе сразу готовый результат.

Конечно, опытный программист данный код напишет за 10 минут не приходя в сознание, но ё-моё, эта сетка даже знает про не самый известный формат FB2.

★★★★★

Последнее исправление: anonymous_incognito (всего исправлений: 1)

Просто какие-то дятлы уже писали и выкладывали в общий доступ код.

А поиск имеющегося по запросу – это и гугл умеет. Только он не очищает лицензию.

По сути здесь смысл только в очистке лицензии исходных кодов (чужих кодов).

Всё равно, что переписать чужой код, немного его изменив.

Попросите её переписать Линукс и выложите в Public domain. Хочу посмотреть зарево пуканов корпов и фанатиков GPL, слившихся в едином пламени. Оно того стоит.

thegoldone ★★
()
Ответ на: комментарий от dataman

Интересен код на C/C++/D/Rust.

Код на Си. Долго не ковырял. К сожалению сгаллюцинировала функцию XmlFindChild, хотя вообще-то странно, что такой нет в libxml2, надо читать, что там вместо неё. Что там может быть ещё не так не смотрел. Но выглядит красиво.

Prompt: «Write in C language a converter from FB2 e-book format to plain text, using correct xpath for xmlns»

Результат:

Converting an FB2 (FictionBook 2) e-book to plain text involves parsing the XML structure and extracting the relevant content while handling namespaces correctly. Below is a simple C program that demonstrates how to achieve this using libxml2, a popular library for processing XML in C.

First, ensure you have libxml2 installed on your system. You can install it via your package manager or build it from source.

Here's the C code:

#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

// Function to extract text from a node
void extract_text(xmlNodePtr node, FILE *output_file) {
    if (node == NULL) return;

    // Check if the node has children
    xmlNodePtr child = node->children;
    while (child != NULL) {
        if (child->type == XML_TEXT_NODE || child->type == XML_CDATA_SECTION_NODE) {
            fprintf(output_file, "%s", (char *)child->content);
        } else if (child->type == XML_ELEMENT_NODE) {
            extract_text(child, output_file);
        }
        child = child->next;
    }
}

// Function to process the book element
void process_book(xmlNodePtr book_node, FILE *output_file) {
    if (book_node == NULL) return;

    xmlNodePtr body_node = xmlFindChild(book_node, BAD_CAST "body");
    if (body_node == NULL) return;

    extract_text(body_node, output_file);
}

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s input.fb2 output.txt\n", argv[0]);
        return 1;
    }

    const char *input_file = argv[1];
    const char *output_file_name = argv[2];

    // Initialize libxml2
    LIBXML_TEST_VERSION

    // Parse the XML file
    xmlDocPtr doc = xmlReadFile(input_file, NULL, 0);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse the XML file.\n");
        return 1;
    }

    // Get the root element
    xmlNodePtr root_element = xmlDocGetRootElement(doc);

    // Open the output file
    FILE *output_file = fopen(output_file_name, "w");
    if (output_file == NULL) {
        fprintf(stderr, "Failed to open output file.\n");
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return 1;
    }

    // Process the book element
    process_book(root_element, output_file);

    // Clean up
    fclose(output_file);
    xmlFreeDoc(doc);
    xmlCleanupParser();

    return 0;
}

### Explanation:

1. **Initialization**: The program initializes libxml2 using `LIBXML_TEST_VERSION`.

2. **Parsing the XML File**: It reads the XML file specified by the user and checks if it was parsed successfully.

3. **Extracting Text**: The `extract_text` function recursively traverses the XML tree, appending text nodes to the output file.

4. **Processing the Book Element**: The `process_book` function finds the `<body>` element within the `<book>` element and calls `extract_text` to extract its contents.

5. **Output**: The extracted text is written to a plain text file specified by the user.

6. **Cleanup**: Finally, the program cleans up by closing the output file, freeing the document, and cleaning up libxml2.

### Compilation:

To compile this program, you need to link against the libxml2 library. Use the following command:

gcc -o fb2_to_txt fb2_to_txt.c -lxml2

### Usage:

Run the compiled program with the input FB2 file and the desired output text file as arguments:

./fb2_to_txt input.fb2 output.txt

This will convert the content of the FB2 file to plain text and save it to `output.txt`.

anonymous_incognito ★★★★★
() автор топика
Ответ на: комментарий от thegoldone

Просто какие-то дятлы уже писали и выкладывали в общий доступ код.

Всё же не так прямолинейно, по-моему. Сетка таки адаптирует код к запросу.

anonymous_incognito ★★★★★
() автор топика

Конечно, опытный программист данный код напишет за

Проблема в том, что для проверки и исправления вывода нейросетки тоже нужен опытный программист.

MoldAndLimeHoney
()