Home > Mobile >  INPUT FORMAT COMPLIANCE: a date prompt with 3 mutable input fields separated by 2 static forward sla
INPUT FORMAT COMPLIANCE: a date prompt with 3 mutable input fields separated by 2 static forward sla

Time:11-28

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.

CodePudding user response:

#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 pinput(prmt, ptrn):
    """
    --Slotted Int Pattern Input--
    """
    def ts_decode(ptrn, ts):
        """
        Recreate the values of vars "sep, cs, e & i"
        by decoding the var "ts" while doing bksp delete.
        """
        if ts == "": return ("", "", ptrn[0], 0)
        lp, st, tp, pcs = len(ptrn), 0, len(ptrn)//2, ""
        for j, l, s in zip(range(1, 9999), range(0, lp, 2), range(1, lp, 2)):
            st  = ptrn[l] len(ptrn[s])
            if st >= len(ts): break
        if ptrn[(j*2)-1] == ts[len(ts)-1]: j = j 1
        #value of "j" (from here) is the slot number.
        sep = ptrn[((j-1)*2)-1]
        csf = 0 if sep == "" else ts.rfind(sep) 1
        cs  = ts[csf:]
        e   = sep if sep == ts[len(ts)-1] else ptrn[(j*2)-2]
        i   = (j*2)-1 if sep == ts[len(ts)-1] else (j*2)-2
        if sep == str(e): i = i-2
        return (sep, cs, e, i)
    ###########################
    ts, sep, i = "", "", 0
    ptxt = "".join([("_"*e) if type(e) is int else e for e in ptrn])
    print(f"{prmt}{ptxt}\r{prmt}", end="")
    sys.stdout.flush()
    while i < len(ptrn):
        e = ptrn[i]
        if type(e) is int:
            cs = ""
            while True:
                cc = getch()
                if cc.isdigit():
                    cs  = cc
                    ts  = cc
                    print(cc, end="")
                    sys.stdout.flush()
                    if len(cs) == e: break
                elif ord(cc) == 127: #bksp support
                    if not ts == "":
                        tsl = len(ts)
                        pln = len(prmt)
                        tln = len(ptxt)
                        sub = 2 if ts[tsl-1] == sep else 1
                        print(f"\r{' '*(tsl pln tln)}\r", end="")
                        ts = ts[:tsl-sub]
                        print(f"{prmt}{ptxt}\r{prmt}{ts}", end="")
                        sys.stdout.flush()
                        sep, cs, e, i = ts_decode(ptrn, ts)
                elif ord(cc) == 13: #enter return support
                    print()
                    return ts
        elif type(e) is str: #add sep
            sep = e
            print(e, end="")
            ts  = e
            sys.stdout.flush()
        i  = 1
    print()
    return ts

if __name__ == "__main__": #test
    rtag = 0
    if rtag == 0:
        prmt = "Input Date and Time: "
        ptrn = [4, "/", 2, "/", 2, " ", 2, ":", 2, ":", 2, ""]
        ts = pinput(prmt, ptrn)
        print(f"{ts=}")
    if rtag == 1:
        pass
  • Related