Генератор XML со случайными значениями через скрипт Python

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

Задача:

Создать скрипт Python для генерирования XML-чеков со случайными значениями в определённом диапазоне.

Пример чека:

<?xml version="1.0" encoding="UTF-8"?>
<Cheque
    inn="0000000000"
    kpp="000000000"
    address="Test"
    name="Test"
    kassa="1"
    shift="1"
    number="1"
    datetime="0101150000"
>
    <Bottle 
        price="10.00"
        barcode="22N00000XOPN13MM66T0HVF311220130003476539219152175585956302712947101"
        ean="4607005090812"
        volume="1.0000"
    />
</Cheque>

Сделать нужно по этой XSD схеме:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Cheque" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Cheque">
        <xs:complexType>
            <!-- случайное из файла -->
            <xs:attribute name="inn" type="IN" use="required" />
            <!-- случайное в соответствие с типом-->
            <xs:attribute name="kpp" type="KP" />
            <!-- случайный набор русских букв и 2ух пробелов, общая длина от 20
до 100 -->
            <xs:attribute name="address" type="ADDRESS" use="required" />
            <!-- случайный набор русских букв длиной от 10 до 20-->
            <xs:attribute name="name" type="xs:string" use="required" />
            <!-- случайный набор латинских букв и цифр длиной от 6 до 12-->
            <xs:attribute name="kassa" type="xs:string" use="required" />
            <!-- случайное в соответствие с типом-->
            <xs:attribute name="shift" type="xs:int" use="required" />
            <!-- случайное в соответствие с типом-->
            <xs:attribute name="number" type="xs:int" use="required" />
            <!-- случайное в соответствие с типом-->
            <xs:attribute name="datetime" type="DT" use="required" />
            <xs:sequence>
                <xs:choice minOccurs="1" maxOccurs="unbounded">
    <xs:element name="Bottle">
        <xs:complexType>
            <!-- случайное от 100.00 до 1000.00 -->
            <xs:attribute name="price" type="PRICE" use="required"/>
            <!-- случайное в соответствие с типом-->
            <xs:attribute name="barcode" type="BK" use="required" />
            <!-- случайное из файла -->
            <xs:attribute name="ean" type="EAN" use="required" />
            <!-- случайное от 0.1000 до 3.0000 с шагом 0.05-->
            <xs:attribute name="volume" type="VOLUME" />
        </xs:complexType>
    </xs:element>
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
        <xs:unique name="bottleBarcode">
            <xs:selector xpath="Bottle" />
            <xs:field xpath="@barcode" />
        </xs:unique>
    </xs:element>
 
    <xs:simpleType name="IN">
        <xs:restriction base="xs:string">
            <xs:pattern value="(от 1 до 10\d{10}|\d{12})"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="KP">
        <xs:restriction base="xs:string">
            <xs:pattern value="(от 1 до 10\d{9}|)"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="DT">
        <xs:restriction base="xs:string">
            <xs:pattern value="[0-3][0-9][0-1][0-9][0-9]{2}[0-2][0-9][0-5][0-9]"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="BK">
        <xs:restriction base="xs:string">
            <xs:pattern value="\d\dN\w{20}\d[0-1]\d[0-3]\d{10}\w{31}"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="EAN">
        <xs:restriction base="xs:string">
            <xs:pattern value="(от 1 до 10\d{8}|\d{13}|\d{12}|\d{14})"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="PRICE">
        <xs:restriction base="xs:string">
            <xs:pattern value="[-]?\d+\.\d{0,2}"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="VOLUME">
        <xs:restriction base="xs:string">
            <xs:pattern value="(от 1 до 10\d+\.?\d{0,4}|)"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="ADDRESS">
        <xs:restriction base="xs:string">
            <xs:maxLength value="128"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

Вот мой скрипт:

import xml.etree.ElementTree as ET
import random
import string

# Читаем содержимое файлов EAN.txt и INN.txt
with open("EAN.txt", "r") as f_ean:
    ean_list = [line.strip() for line in f_ean]

with open("INN.txt", "r") as f_inn:
    inn_list = [line.strip() for line in f_inn]

# Создаем корневой элемент
cheque = ET.Element("Cheque")

ean = random.choice(ean_list)
inn = random.choice(inn_list)

# Создаём функцию генератор рандомных зачений

def generate_random_value(data_type, min_value, max_value, step=None):
    if data_type == "int":
        return str(random.randint(min_value, max_value))
    elif data_type == "float":
        if step is None:
            return random.uniform(min_value, max_value)
        else:
            return round(random.uniform(min_value, max_value), step)
    elif data_type == "str_rus":
        return ''.join(random.choice(string.ascii_letters + "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ") for _ in range(random.randint(10, 20)))
    elif data_type == "str_lat":
        return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(6, 12)))
    elif data_type == "barcode":
        return "22N" + "".join(random.choice(string.ascii_uppercase + string.digits) for _ in range(12)) + "MM66T0HVF311220130003476539219152175585956302712947101"
    elif data_type == "datetime":
        return f"{random.randint(1, 31)}{random.randint(1, 12)}{random.randint(2000, 2024)}{random.randint(0, 23)}{random.randint(0, 59)}{random.randint(0, 59)}"
    else:
        raise ValueError(f"Неизвестный тип данных: {data_type}")



# Добавляем атрибуты корневому элементу
cheque.set("inn", inn)
# случайное в соответствие с типом
cheque.set("kpp", generate_random_value("str_lat", 9, 10))
# случайный набор русских букв и 2ух пробелов, общая длина от 20 до 100
cheque.set("address", generate_random_value("str_rus", 20, 100))
# случайный набор русских букв длиной от 10 до 20
cheque.set("name", generate_random_value("str_rus", 10, 20))
# случайный набор латинских букв и цифр длиной от 6 до 12
cheque.set("kassa", generate_random_value("str_lat", 6, 12))
# случайное в соответствие с типом
cheque.set("shift", generate_random_value("int", 1, 10))
# случайное в соответствие с типом
cheque.set("number", generate_random_value("int", 1, 10))
# случайное в соответствие с типом
cheque.set("datetime", "0101150000")

# Создаем элемент "Bottle"
bottle = ET.Element("Bottle")

# Добавляем атрибуты элементу "Bottle"

# случайное от 100.00 до 1000.00
bottle.set("price", "10.00")
# случайное в соответствии с типом
bottle.set("barcode", "22N00000XOPN13MM66T0HVF311220130003476539219152175585956302712947101")
bottle.set("ean", ean)
# случайное от 0.1000 до 3.0000 с шагом 0.05
bottle.set("volume", "1.0000")

# Добавляем элемент "Bottle" к корневому элементу
cheque.append(bottle)

xml_string = ET.tostring(cheque, encoding="unicode")

# Записываем XML строку в файл
with open("cheque.xml", "w", encoding="utf-8") as f:
    f.write(xml_string)

Ответы (0 шт):