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