qbasic к python как

Я пытаюсь преобразовать старый код qbasic (старый dos basic) в python. Я знаю Python, но не очень много qbasic (кроме угадывания значения синтаксиса). Это код qbasic

1020 DIM XS(499), A(504), V(99)
1560 GOSUB 2600                 'Get coefficients

2600 REM Get coefficients
2660 CODE$ = "A"
2680 M% = 3
2690    FOR I% = 1 TO M%        'Construct CODE$
2700        GOSUB 2800          'Shuffle random numbers
2710        CODE$ = CODE$ + CHR$(65 + INT(25 * RAN))
2720    NEXT I%
2730 FOR I% = 1 TO M%           'Convert CODE$ to coefficient values
2740    A(I%) = (ASC(MID$(CODE$, I% + 1, 1)) - 77) / 10
2750 NEXT I%
2760 RETURN
2800 REM Shuffle random numbers
2810 IF V(0) = 0 THEN FOR J% = 0 TO 99: V(J%) = RND: NEXT J%
2820 J% = INT(100 * RAN)
2830 RAN = V(J%)
2840 V(J%) = RND
2850 RETURN

Похоже, что он отображает коды ASCII на случайные числа, но мне не ясно, как, поскольку я не знаком с синтаксисом J% и V(J%) и т. Д. (Не знаю, что означает%)

2 ответа

Как уже упоминалось, в QBasic %, $ а также # обозначить тип данных переменной. В Python вам не нужно указывать типы данных переменных, но в QBasic это выглядит так:

QBasic
I%   ' % = integer variable
str$ ' $ = string variable
f#   ' # = floating point variable

И если вы хотите преобразовать функции QBasic, посмотрите эти вопросы: Python эквивалент среднего и Python получить значение ASCII

QBasic              Python
str$ = "water"      str = "water"
ASC("A")            ord("A")     // result 65
MID$(str$, 3, 2)    str[3,(3+2)] // result "te"
CHR$(65)            chr(65)      // result "A"

Это больше похоже на GW-BASIC, чем на QBasic, хотя это также допустимо и для QBasic. Имена переменных GW-BASIC написаны заглавными буквами, тогда как QBasic не чувствителен к регистру, но в именах разрешены символы нижнего регистра.

Символы постфиксного типа уже упоминались в другом ответе и комментарии к вопросу:%обозначает целочисленные переменные и$это для струн. Что не было упомянуто, так это то, чтоA,A%,A$и массивыA(),A%(),A$()шесть различных переменных. Поэтому при переводе кода очень близко к оригиналу лучше закодировать постфикс типа в имя на стороне Python. Если только вы не уверены, что нет имен, просто различающихся по типу. Учитывая, что большинство программ GW-BASIC использовали имена длиной один или два — чтобы оставаться обратно совместимыми со старыми диалектами Microsoft BASIC — «коллизии» в более крупных программах были почти данностью.

У Python нетGOTO/RETURN, поэтому нужно либо встроить эти подпрограммы, либо определить функцию и объявить локальные скалярные переменные какglobal.

XS()не используется иRANне инициализируется явно, но он должен быть на Python. Итак, первый перевод может выглядеть так:

      from random import random


def shuffle_random_numbers():
    global J_int, RAN

    if V_array[0] == 0:
        for J_int in range(100):
            V_array[J_int] = random()

    J_int = int(100 * RAN)
    RAN, V_array[J_int] = V_array[J_int], random()


def get_coefficients():
    global CODE_str, M_int, I_int, RAN
    #
    # Generate a four letter string starting with "A" followed by three random
    # characters from the range A..Y (inclusive).
    #
    CODE_str = "A"
    M_int = 3
    for I_int in range(1, M_int + 1):
        shuffle_random_numbers()
        CODE_str += chr(65 + int(25 * RAN))
    #
    # Convert the letters into values between -1.2 and 1.2.
    # 
    # "A" = -1.2, "B" = -1.1, "C" = -1.0, "D" = -0.9, …, "X": 1.1, "Y" = 1.2
    # 
    for I_int in range(1, M_int + 1):
        A_array[I_int] = (ord(CODE_str[M_int]) - 77) / 10


RAN = 0  # Initialised implicitly in the BASIC code.
A_array = [0] * 505
V_array = [0] * 100
get_coefficients()

shuffle_random_numbers()выглядит фальшиво. Либо это кажется действительно ненужным, поскольку он просто сохраняет/результаты и использует последний результат для выбора одного из сохраненных чисел и заменяет его новым случайным числом. Нравиться /RNDон возвращает случайные числа от 0 до 1; только в другом порядке. Если это потому, что первоначальный программист чувствовал необходимость сделать случайные числа «более случайными», то откажитесь от этой функции и просто используйте .

Если этот конкретный порядок имеет отношение к программе, вы не можете просто использоватьrandom()но необходимо воссоздать исходный генератор псевдослучайных чисел диалекта BASIC, используемый для запуска исходной программы. Если это GW-BASIC, то существует точная реализация с открытым исходным кодом, написанная на Python: PC-BASIC.

Дляget_coefficients(), предполагаяM%иI%используются только локально, и используя аргументы и возвращаемое значение, мы можем оказаться здесь:

      import random
from string import ascii_uppercase

A_TO_Y = ascii_uppercase[:-1]
assert A_TO_Y[-1] == "Y"


def set_coefficients(values):
    code = "A" + "".join(random.choice(A_TO_Y) for _ in range(3))
    #
    # Convert the letters into values between -1.2 and 1.2.
    #
    # "A" = -1.2, "B" = -1.1, "C" = -1.0, "D" = -0.9, …, "X": 1.1, "Y" = 1.2
    #
    offset = ord(A_TO_Y[0]) + len(A_TO_Y) // 2
    for i, letter in enumerate(code, 1):
        values[i] = (ord(letter) - offset) / 10

    return code


def main():
    values = [0] * 505
    code = set_coefficients(values)


if __name__ == "__main__":
    main()

Обратите внимание на изменение имени функции, поскольку ни один читатель не ожидаетget_*()функция для фактической установки значений в последовательности, заданной в качестве аргумента.

Другие вопросы по тегам