Функция присваивающая каждой карточке новый id

Marina10

Новичок
Пользователь
Апр 29, 2020
12
0
1
Мне для класса необходимо создать функцию, которая сможет изменять (создавать) новые id для новых карточек в картотеке. Функция должна изменять последние буквенное значение в след порядке:
z --> aa --> ab -->...-->az --> ba--> bb -->bc -->..-->bz --> ca -->...-->cz ---> zz --> aaa

И если дано:
notice_1 = "1ab3g"
notice_2 = "1ab3ga"

def next_number(id_num):
abc = list(" abcdefghijklmnoprstuvwxyz")

То функция должна возвращать "1ab3h" от next_number(notice_1)
Так как я еще новичок, то мне сложно представить как это можно воплотить.
 

borntohack

змееуст
Команда форума
Модератор
Апр 22, 2020
78
62
18
39
Москва, РФ
Давай разбираться:
первое, что должна сделать твоя функция - это узнать последний символ в строке id_num.
Поскольку строка - это итерируемый объект, сделать это довольно просто по индексу [-1]
Затем, нам нужно определить, не равен ли этот последний символ z, и если равен, то новый должен быть aa,
а если не равен - то новый должен быть следующим за этим символом индексом строки abc
Реализация (на начальном уровне):
Python:
abc = "abcdefghijklmnopqrstuvwxyz"
def next_number(id_num):
    cur_char = id_num[-1]
    if cur_char == "z":
        new_char = "aa":
    else:
        new_char = abc[abc.index(cur_char)+1]
    return idnum[:-1]+newchar

notice_1 = "1ab3g"
print(next_number(notice1))

Разумеется, этот код поддается оптимизации, но для понимания оставлю его таким
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Вот решение методом перевода строки в число и обратно:
Python:
def next_number(s):
    abc = list("abcdefghijklmnopqrstuvwxyz")

    # получаем буквенное окончание строки
    end = ''
    for i in s[::-1]:
        if not i.isdigit():
            end += i
        else:
            break

    # буквенное окончание строки
    end = end[::-1]

    # начало строки
    begin = s[:-len(end)]

    # цифровое значение окончания
    n = sum([(abc.index(item) + 1) * len(abc) ** i for i, item in enumerate(end[::-1])])

    # увеличиваем значение
    n += 1
    # перевод обратно в строку
    end = ''
    while True:
        if n > len(abc):
            if n % len(abc) == 0:
                end += abc[n % len(abc) - 1]
                n = n // len(abc) - 1
            else:
                end += abc[n % len(abc) - 1]
                n = n // len(abc)
        else:
            end += abc[n - 1]
            break

    # возвращаем строку с новым окончанием
    return begin + end[::-1]


notice_1 = "1ab3nbvmsm59y895wynn896y93zzg"
notice_2 = '1ab3aa'
notice_3 = '1ab3aab'
notice_4 = '1ab3zzz'
print(next_number(notice_1))
print(next_number(notice_2))
print(next_number(notice_3))
print(next_number(notice_4))
 

borntohack

змееуст
Команда форума
Модератор
Апр 22, 2020
78
62
18
39
Москва, РФ
Прошу прощения, неверно прочитал условия задачи.
Абсолютно верную логику подсказывает Дима. Нужно "проваливаться" вглубь от конца при достижении z и инкрементировать значение предыдущего индекса, сбрасывая текущий индекс на начало алфавита.

Однако, у вас есть условие, которое противоречит заданной логике. ID содержит так же и цифры, которые не содержатся в алфавите.
Я позволил себе представить, что цифры в алфавите так же должны быть, и написал неоторую развернутую версию решения:
Python:
abc = "0123456789abcdefghijklmnopqrstuvwxyz"
notice_1 = "1ab3g"


def update_id(some, pivot=-1):
    if some[pivot] == abc[-1]:
        if len(some)+pivot == 0:
            some[0:pivot] = abc[0]
        else:
            update_id(some, pivot-1)
            some[pivot] = abc[0]
    else:
        some[pivot] = abc[abc.index(some[pivot])+1]

# для тестов генерируем 10000 идентификаторов от notice_1
for i in range(100000):
    notice_1 = list(notice_1)
    update_id(notice_1)
    print("".join(notice_1))

Решение основывается на принципе изменяемости (мутабельности) списков и рекурсии.
В нулевой строке мы задаем алфавит (т.е. порядок следования элементов для замены).
Внутри цикла for, где генерируются идентификаторы - приводим наш notice_1 к списку, чтобы иметь возможность менять его элементы "на лету" не прибегая к возвратам и новым заменам.

А вот что происходит внутри функции update_id.
"Точка привязки" (pivot) - это индекс обрабатываемого элемента. По умолчанию = -1 - т.е. последний элемент от конца
Если в нашем списке последний элемент равен "z" (на самом деле последнему символу алфавита), то мы выполним ту же функцию для элемента -2 - это предпоследний элемент, тем временем имеющийся "z" мы заменим на первый символ из алфавита (в нашем случае - это 0)
Если же рабочий элемент (по индексу pivot) - не является "z" - то мы просто заменим его на следующий символ из алфавита.
Тут нужно учесть, что когда мы сталкиваемся с ситуацией, в которой уже все символы заменились на "z" - нам необходимо "обнулить строку" и добавить к ней еще один элемент. Делается это при условии, что длина массива стала быть равна сдвигу нашей точки привязки (pivot)
 

dima_diakivnych

Новичок
Пользователь
Апр 29, 2020
2
1
3
Каждый раз ты в функцию принимаешь строку текущего состояния. Идешь с конца по строчке и пытаешься увеличить букву: если получилось, то увеличиваешь ее и и делаешь все символы, что правее равными "a" и сразу возвращаешь нашу строку, иначе идешь дальше. Когда ты дойдешь до начала, и ничего не изменишь, то значить строка состоит со всех символом "z". Тогда тебе нужно возвращать строку длины на 1 больше, в которой все символы равны "a".
Примеры
ab->ac, ac->ad, abz->aca, aca->acb, acb->acc, azzzz->baaaa
 
  • Мне нравится
Реакции: borntohack

Marina10

Новичок
Пользователь
Апр 29, 2020
12
0
1
Давай разбираться:
первое, что должна сделать твоя функция - это узнать последний символ в строке id_num.
Поскольку строка - это итерируемый объект, сделать это довольно просто по индексу [-1]
Затем, нам нужно определить, не равен ли этот последний символ z, и если равен, то новый должен быть aa,
а если не равен - то новый должен быть следующим за этим символом индексом строки abc
Реализация (на начальном уровне):
Python:
abc = "abcdefghijklmnopqrstuvwxyz"
def next_number(id_num):
    cur_char = id_num[-1]
    if cur_char == "z":
        new_char = "aa":
    else:
        new_char = abc[abc.index(cur_char)+1]
    return idnum[:-1]+newchar

notice_1 = "1ab3g"
print(next_number(notice1))

Разумеется, этот код поддается оптимизации, но для понимания оставлю его таким
Но, тогда получается, что если я например возьму строку "1ab3ga" то вместо "1ab3gb" функция выводит "1ab3gab" где "a" совершенно лишняя .
 

Форум IT Специалистов