简体   繁体   中英

Function in python to find the uppercase characters from a sum of ascii numbers

I'm trying to write a function to find the text from a sum of ascii numbers. All characters are uppercase , and if for example I get 155 , the function need to return AZ (65+90). Think of it like columns in an Excel table: it goes from A to Z, then AA, AB...AZ, BA, BB and etc. It needs to work for up to 4 digits. I'm trying a recursive function, but it has some errors. If I give the function 270 -> it return AAAK , not ZZZ , because I check if 65(A) fits in that number , then I go to the next if it doesn't (with the second if: number % asc + asc ). Another error is in the output of the code: 130+90 works well , AAZ , but if I add 1 it should give me ABA . In these cases I think I'm doing things wrong the most. Initially I wanted to use integer division ( // ) and modulo ( % ), but it didn't work.

def ascii(number):
    result = ""
    if number > 90:
        for asc in range(65, 91):
            if number % asc + asc in range(65, 91):
                result += chr(asc)
                result += ascii(number - asc)
                break
    else:
        result += chr(number)

    return result


if __name__ == '__main__':
    result = ""
    print(ascii(131))
    print(ascii(130+90))
    print(ascii(130+90+1))
    print(ascii(130+90+39))

#output: AB, AAZ, BAZ, UTZ

Searching recursively is fine, the problem is that you don't set a limit to how deep it need to go, that is why for 270 it goes 4 levels to AAAK and not 3 to ZZZ.

So first we need to determine how deep we need to go, then the base case for the recursive function now become: in the base level return the character if the value is correct otherwise return nothing, and for the rest, for each character, we check if we get a result from the recursive case, if we do we're done otherwise we continue and if no match simple return nothing.

Something like

import itertools
A = ord("A")
Z = ord("Z")

def length(num):
    if num < A:
        return 0
    for n in itertools.count(1):
        if A*n <= num <= Z*n:
            return n
        elif num <= A*n:
            break
    return 0

def search_ascii(num, level):
    if level<1:
        return ""
    if level==1:
        if A <= num <= Z:
            return chr(num)
        return ""
    for n in range(A,1+Z):
        r = search_ascii(num-n,level-1)
        if r:
            return chr(n)+r
    return ""
    

def to_ascii(num):
    n = length(num)
    if not n:
        raise ValueError("value too small")
    return search_ascii(num,n)


print(to_ascii(131))
print(to_ascii(130+90))
print(to_ascii(130+90+1))
print(to_ascii(130+90+39))
print(to_ascii(270))
print(to_ascii(155))

and the output

AB
AAZ
ABZ
OZZ
ZZZ
AZ

the non-recursive version can be done with itertools.product like so:

def to_ascii_it(num):
    n = length(num)
    if not n:
        raise ValueError("value too small")
    for chars in itertools.product(range(A,1+Z), repeat=n):
        if sum(chars)==num:
            return "".join(map(chr,chars))

我觉得这个设计不是很清楚,比如155既可以是65+90的组合,也可以是66+89的组合,甚至更多的其他组合。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM