INPUT FORMAT COMPLIANCE: a date prompt with 3 mutable input fields separated by 2 static forward slashes, with set ranges for each feild

Question:

I am trying to create a prompt that is either separated by hard slashes or slashes appear after specified input range, all on a single line.

i want:

Enter your age (M/D/Y): int / int / int #where the slashes are fixed and part of the prompt

not: M:
     D:
     Y:

example:

Enter the date M/D/Y: '12'**/**'12'**/**'1234'
                        0,1,/    0,1,/ 

Ideal: the slashes are static but the input fields between are mutable, and cursor skips slashes.

**or:**the slash appears after populating the specified range…and the integer input field ranges would be set at 0:1,0:1,0:3

(mm) if users enters two integers, backslash appears 
(dd) if users enters two integers, backslash appears
(yyyy) user completes the range (or not)

User is unable to enter subsequent integers out of range.

nothing seemed to be what I’m after. the closest info i could find was using datetime but that just sorts out the input, i want actual hard slashes to appear, separating the input fields, or appear after input and stay.

printing it like that isn’t an issue, and the integer input field ranges would be set at 0:1,0:1,0:3

being a noob i’m not certain if py is even capable of such a demand.

Asked By: Raven

||

Answers:

#A solution was provided elsewhere, posting with Author's permission.

"""PINPUT, AN INPUT FORMAT COMPLIANCE MODULE FOR DATE/TIME ENTRY"""
"                  AUTHOR: INDRAJIT MAJUMDAR                      "

    import sys
 
try:
    #for windows platform.
    from msvcrt import getwch as getch
except ImportError:
    #for linux, darwin (osx), and other unix distros.
    def getch():
        """
        Gets a single character from STDIO.
        """
        import sys
        import tty
        import termios
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            return sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old)
 
def flsp_input(prmt, ptrn, otyp="t"): #otyp=[s=string, t=tuple, p=ptrn]
    """
    --flsp_input:
    --Fixed Length Slotted Pattern Input [int, str]--
            Licence: opensource
            Version: 1.1
            Author : [email protected]
    """
    def fout(ts, ptrn, otyp):
        fs, tpl = 0, []
        for i, p in enumerate(ptrn):
            if p[2] == "":
                csd = ts[fs:]
            else:
                fi = ts[fs:].find(p[2])
                if fi == -1:
                    csd = ts[fs:]
                else:
                    csd = ts[fs:fs+fi]
            fs += p[1]+len(p[2])
            if otyp == "s": out = ts
            if otyp == "t": tpl.append(csd)
            if otyp == "p": ptrn[i].append(csd)
        if otyp == "s": out = fout
        if otyp == "t": out = tuple(tpl)
        if otyp == "p": out = ptrn
        return out
    
    i, ts, plts, = 0, "", 0
    ptxt = "".join([f"{'_'*e[1]}{e[2]}" for e in ptrn])
    print(f"{prmt}{ptxt}r{prmt}", end="")
    sys.stdout.flush()
    while i < len(ptrn):
        ptype, plen, psep = ptrn[i]
        while True:
            cc = getch()
            if ord(cc) == 127: #bksp
                frm = 0 if i == 0 else ts.rfind(ptrn[i-1][2])+1
                cplf = ts[frm:]
                bkstp = 2 if cplf == "" and i != 0 else 1
                ts = ts[:len(ts)-bkstp]
                if bkstp == 2: i -= 1
                ptype, plen, psep = ptrn[i]
                plts = sum((ptrn[j][1]+len(ptrn[j][2]) for j in range(i)))
                print(f"r{prmt}{ptxt}r{prmt}{ts}", end="")
                continue
            if ord(cc) == 13: #enter
                print()
                return fout(ts, ptrn, otyp)
            try:
                cc = int(cc)
            except ValueError:
                cc = cc
            if type(cc) is ptype:
                cc = str(cc)
                ts += cc
                print(cc, end="")
                sys.stdout.flush()
                if len(ts) - plts == plen:
                    print(psep, end="")
                    ts += psep
                    plts = len(ts)
                    sys.stdout.flush()
                    break
        i += 1
    print()
    return fout(ts, ptrn, otyp)
 
if __name__ == "__main__":
    prmt = "Input Date and Time: "
    ptrn = [[int, 2, "/"], [int, 2, "/"], [int, 4, " "],
            [int, 2, ":"], [int, 2, ":"], [int, 2, "."],
            [int, 3, " "], [str, 2, ""]]
    #ptrn = [[str, 2, ":"], [int, 2, " "], [str, 1, " "],
    #       [int, 4, ""]]
    ts = pinput(prmt, ptrn)
    print(f"{ts=}")
Answered By: Raven
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.