def intf_INCR(E): """An increment function. Will increment a value by adding 1. Will also try to add one to the value of a symbol (leaving nothing). Incrementing text will append an extra copy of the last letter of the original string. Lists increment by adding another copy of the last item.""" term = E.The.StackPop() if term.whatami == 'SYM': if E.symtab[term.val].whatami == 'VAL': # Needs a new object to break old refs links. v = objectifier.StackOB_VAL(E.symtab[term.val].val + 1) E.symtab[term.val] = v elif E.symtab[term.val].whatami == 'TXT': # Needs a new object to break old refs links. t = objectifier.StackOB_TXT(E.symtab[term.val].val + E.symtab[term.val].val[-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'LST': # Needs a new object to break old refs links. t = objectifier.StackOB_LST(E.symtab[term.val].val + [E.symtab[term.val].val[-1]]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'SYM': pass # This is not complete. Because it's hard. elif term.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(term.val + 1)) elif term.whatami == 'TXT': newseq = term.val + term.val[-1] E.The.StackPush(objectifier.StackOB_TXT(newseq)) elif term.whatami == 'LST': newseq = term.val + [term.val[-1]] # Orig. list + last item. E.The.StackPush(objectifier.StackOB_LST(newseq)) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), term])
def intf_LADD(E): """List addition operator where lists are the focus. Compare to `+` where items are the focus. Given the existence of v1 and v2, all input possibilities are valid. Only SYMs that ultimately refer to LSTs are resolved prior to the actual operation. Name space lists are lost. L ? :+ -> append item to end of list ? L :+ -> prepend item to front of list L L :+ -> concatenate lists notL notL :+ -> make list containing [notL notL] Examples: [4 8] 7 :+ -> [4 8 7] 4 [4 8] :+ -> [4 4 8] [1 2 3] |Q sto |Q 4 :+ -> [1 2 3 4] [2 ''two''] [3 3 3] :+ -> [2 ''two'' 3 3 3] [3 3 3] [2 2] :+ -> [3 3 3 2 2] ''listify'' ''me'' :+ [''listify'' ''me''] """ v2 = E.The.StackPop() v1 = E.The.StackPop() if inc.is_essentially_a(E, v1, 'LST'): v1 = E.resolve_symbol(v1) if inc.is_essentially_a(E, v2, 'LST'): v2 = E.resolve_symbol(v2) if not v1.whatami == 'LST' and not v2.whatami == 'LST': # notL notL E.The.StackPush(objectifier.StackOB_LST([v1, v2])) elif v1.whatami == 'LST' and v2.whatami == 'LST': E.The.StackPush(objectifier.StackOB_LST(v1.val + v2.val)) elif v2.whatami == 'LST': # v1 must be something else. E.The.StackPush(objectifier.StackOB_LST([v1] + v2.val)) elif v1.whatami == 'LST': # v2 must be something else. E.The.StackPush(objectifier.StackOB_LST(v1.val + [v2])) else: print( "Error: What the hell have you done!? This should never have happend. See `intf_LADD`." )
def intf_DECR(E): """A decrement function. Will decrease a value by subracting 1. Will also try to subtract one from the value of a symbol (leaving nothing). Decrementing text will remove the last letter of the original string. Lists decrement by removing the last item.""" term = E.The.StackPop() if term.whatami == 'SYM': if E.symtab[term.val].whatami == 'VAL': # Needs a new object to break old refs links. v = objectifier.StackOB_VAL(E.symtab[term.val].val - 1) E.symtab[term.val] = v elif E.symtab[term.val].whatami == 'TXT': # Needs a new object to break old refs links. t = objectifier.StackOB_TXT(E.symtab[term.val].val[0:-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'LST': # Needs a new object to break old refs links. t = objectifier.StackOB_LST(E.symtab[term.val].val[0:-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'SYM': pass # This is not complete. Because it's hard. elif term.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(term.val - 1)) elif term.whatami == 'TXT': newseq = term.val[0:-1] E.The.StackPush(objectifier.StackOB_TXT(newseq)) elif term.whatami == 'LST': newseq = term.val[0:-1] E.The.StackPush(objectifier.StackOB_LST(newseq)) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), term])
def intf_ENTDUPS(E): """Returns a list of every entity ID in the memory model which has an earlier (lower EID) corresponding entity which shares all of the exact same points. This is handy for managing duplicate entities. To completely clean up a model of duplicated entities, all edup? ~ -> """ if not inc.entid_or_LST_of_entids(E.The,1): print("Input Error: doubles") print(intf_ENTERASE.__doc__) return # Without doing much of anything. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. else: myeids= [ myeids ] # Also a (1 item) list of ints. some_doubles= list() for myeid in myeids: if myeid in MMEL.El: # Check if eid exists. if not myeid in some_doubles: new_doubles= MMEL.find_doubles_of(MMEL.El[myeid]) some_doubles+= new_doubles else: print("WARNING: Entity ID# %d does not exist." % myeid) if some_doubles: some_doubles_so= [objectifier.StackOB_VAL(eid) for eid in some_doubles] some_doubles_so= objectifier.StackOB_LST(some_doubles_so) E.The.StackPush(some_doubles_so) else: E.The.StackPush( objectifier.StackOB_LST( list() ))
def intf_TAGQUERY(E): """From level one, a TXT object or a list of TXT objects is taken off the stack. The entities which are tagged with the specified text items are returned in a list. An empty list is returned if no entities are tagged with the supplied tags. ''mytag'' tag? -> [<entID> <entID>] [''mytag1'' ''mytag2''] tag? -> [<entID> <entID] This will find any entities tagged with both "roof" and "house". [''roof'' ''house''] tag? -> [<entID> <entID>] This usage implies an *and* operation where all tags supplied must apply to the entity. To achieve an *or* effect use a construction like this. [''roof'' ''house''] tag? [''roof'' ''barn''] tag? + -> [<entID> <entID>] """ if not inc.TXT_or_LST_of_TXTs(E.The,1): print("Input Error: tag?") print(intf_TAGQUERY.__doc__) return # Without doing much of anything. mytags= E.The.StackPop().val if type(mytags)==type(list()): #mytags= map(lambda x:x.val, mytags) # Should now be a list of TXTs. mytags= [x.val for x in mytags] # Should now be a list of TXTs. else: mytags= [ mytags ] # Also a (1 item) list of ints. qualifying_ents= list() for myeid in MMEL.El.keys(): alltagshere= True # Assume they're here until one is not found. for mytag in mytags: #print("Searching entity #%d for tag ''%s''" % (myeid,mytag)) if not MMEL.El[myeid].has_tag(mytag): alltagshere= False break if alltagshere: qualifying_ents.append( objectifier.StackOB_VAL(myeid) ) E.The.StackPush( objectifier.StackOB_LST(qualifying_ents) )
def intf_ENTDUP(E): """Supply an entity ID or list of entity IDs on the stack and this function will create a new entity of the same type and using the same points. The new entity id or list of ids will be returned to the stack.""" if not inc.entid_or_LST_of_entids(E.The,1): print("Input Error: entdup") print(intf_ENTDUP.__doc__) return # Without doing much of anything. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. listify= True else: myeids= [ myeids ] # Also a (1 item) list of ints. listify= False new_eid= list() for myeid in myeids: if myeid in MMEL.El: # Check if eid exists. src_ent= MMEL.El[myeid] new_ent= src_ent.duplicate() MMEL.add_ent(new_ent) if listify: new_eid.append( objectifier.StackOB_VAL(new_ent.eid) ) else: new_eid= objectifier.StackOB_VAL(new_ent.eid) else: print("WARNING: Entity ID# %d does not exist." % myeid) if new_eid: if listify: new_eid= objectifier.StackOB_LST(new_eid) E.The.StackPush(new_eid)
def intf_LMUL(E): """List multiplication operator where lists are the focus. Compare to `*` where items are the focus. All SYMs are resolved to their referent. The input requires only that v1 or v2 or both must resolve to a VAL. All other combinations are valid. A negative VAL as the multiplier will reverse the order of mulitplied lists. L V :* -> replication of list items in list, commutative T V :* -> put text item in list with copies, commutative V V :* -> put v2 in list with v1 copies, not commutative Examples: [1 2 3] 2 :* -> [1 2 3 1 2 3] 2 [1 2 3] :* -> [1 2 3 1 2 3] ''abc'' 2 :* -> [''abc'' ''abc''] 4 3 :* -> [4 4 4] 3 4 :* -> [3 3 3 3] [0 1] -3 :* -> [1 0 1 0 1 0] """ if not (inc.VAL(E, 1) or inc.VAL(E, 2)): print("Input Error: lmul") print(intf_LMUL.__doc__) return # Without doing much of anything. v2 = E.resolve_symbol(E.The.StackPop()) v1 = E.resolve_symbol(E.The.StackPop()) if not v2.whatami == 'VAL': v1, v2 = v2, v1 if v1.whatami == 'LST': outlist = v1.val * abs(int(v2.val)) else: # Both are vals. outlist = [v1] * abs(int(v2.val)) if v2.val < 0: outlist = outlist[::-1] E.The.StackPush(objectifier.StackOB_LST(outlist))
def intf_ENTPTS(E): """Supply a number on the stack and this function will return the geometry of that entity. If a list of entity IDs is supplied, return geometry data for each.""" if not inc.entid_or_LST_of_entids(E.The,1): print("Input Error: pts") print(intf_ENTPTS.__doc__) return # Without doing much of anything. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. else: myeids= [ myeids ] # Also a (1 item) list of ints. for myeid in myeids: # NEEDS TO CHECK IF EID EXISTS! if myeid in MMEL.El: # Check if eid exists. pids= MMEL.El[myeid].epts # List of point IDs for this entity. for pid in pids: x= mm.Entity.allplist.PLdict[pid].x y= mm.Entity.allplist.PLdict[pid].y z= mm.Entity.allplist.PLdict[pid].z z= objectifier.StackOB_VAL(z) # Can't be just regular Python ints. y= objectifier.StackOB_VAL(y) x= objectifier.StackOB_VAL(x) p= objectifier.StackOB_LST([x, y, z]) p.names= ['x','y','z'] E.The.StackPush(p) else: print("Warning: No entity #%d. Skipping." % myeid)
def intf_POINTFORM(E): """Take 3 values off the stack and make a point formatted list.""" # Preserve the VAL obj (don't take .val) which will compose the gg list. z= E.The.StackPop() y= E.The.StackPop() x= E.The.StackPop() p= objectifier.StackOB_LST([x, y, z]) p.names= ['x','y','z'] E.The.StackPush(p)
def intf_UNDOCHECK(E): """This function puts a live list on the stack that represents what would happen if an undo was executed. If you want to actually proceed with the undo, just eval it. If not, drop it.""" if not E.Undo.StackIsEmpty(): back_procedure= objectifier.StackOB_LST(E.Undo.StackPop()) back_procedure.dead= False # Wake it up for potential action. E.The.StackPush( back_procedure ) # Send it out. else: print("There is nothing to undo!")
def intf_RANGE(E): """Takes a positive integer off the stack and returns a list containing 0 through that number minus 1 in order. To get 1 through N, try: N range |[++::!] map Or this might be easier: N range 1 + """ n= E.The.StackPop() # Magnitude. # Make val ojects out of Python's range command. r= map(objectifier.StackOB_VAL, range(int(n.val))) E.The.StackPush(objectifier.StackOB_LST(r)) # New list on stack.
def intf_ENTPGRAM(E): """Takes an entity or list of entities from v3 and two point formatted lists from v2 and v1 (which could come from a line entity number supplied to the `pts` function) and creates a parallelogram. This parallelogram consists of the original supplied line entity, a new parallel line entity, two new line entites connecting the endpoints of the other lines, and two trifaces which cover the entire area of the parallelogram.""" # !! Need to check for some eids being TRIs. Filter that out. if ( not inc.entid_or_LST_of_entids(E.The,3) or not inc.point_formatted_LST(E.The,2) or not inc.point_formatted_LST(E.The,1) ): print("Input Error: pgram") print(intf_ENTPGRAM.__doc__) return # Without doing much of anything. oB= [ xyz.val for xyz in E.The.StackPop().val ] # A list [3.5 -2 0]. oA= [ xyz.val for xyz in E.The.StackPop().val ] # A list [3.5 -2 0]. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. else: myeids= [ myeids ] # Also a (1 item) list of ints. neweidlist= [] for myeid in myeids: if myeid in MMEL.El: # Check if eid exists. src_ent= MMEL.El[myeid] new_ent= src_ent.duplicate() new_ent.translate([ oB[0]-oA[0], oB[1]-oA[1], oB[2]-oA[2] ]) As= mm.Entity.allplist.PLdict[ src_ent.epts[0] ] Ae= mm.Entity.allplist.PLdict[ src_ent.epts[1] ] Bs= mm.Entity.allplist.PLdict[ new_ent.epts[0] ] Be= mm.Entity.allplist.PLdict[ new_ent.epts[1] ] neweidlist.append(new_ent.eid) MMEL.add_ent(new_ent) line_entS= mm.Line_Entity( [As,Bs] ) neweidlist.append(line_entS.eid) MMEL.add_ent(line_entS) line_entE= mm.Line_Entity( [Ae,Be] ) neweidlist.append(line_entE.eid) MMEL.add_ent(line_entE) tri_entA= mm.Tri_Entity( [As, Ae, Bs] ) neweidlist.append(tri_entA.eid) MMEL.add_ent(tri_entA) tri_entB= mm.Tri_Entity( [Bs, Be, Ae] ) neweidlist.append(tri_entB.eid) MMEL.add_ent(tri_entB) else: print("WARNING: Entity ID# %d does not exist." % myeid) if neweidlist: neweids= objectifier.StackOB_LST( [objectifier.StackOB_VAL(x) for x in neweidlist] ) E.The.StackPush(neweids) OUT.default(MMEL,E) # AUTODUMP
def intf_SHUFFLE(E): """Takes a list item from v1 and returns a list of the same objects in a completely random order. This will shuffle the entire stack. depth 2list shuffle wake ! """ if not inc.LST(E, 1): print("Input Error: shuffle") print(intf_SHUFFLE.__doc__) return # Without doing much of anything. v1 = E.The.StackPop().val # List to be shuffled. import random random.shuffle(v1) E.The.StackPush(objectifier.StackOB_LST(v1))
def intf_2LIST(E): """Takes a number n and n more stack objects and produces a list of size n.""" qty= E.The.StackPop().val # The quantity of list to create. if qty > E.The.StackSize() or qty < 1: qty= E.The.StackSize() templist= list() while qty: templist.append( E.The.StackPop() ) qty -= 1 templist.reverse() object= objectifier.StackOB_LST(templist) object.dead= True E.The.StackPush(object)
def intf_TAILN(E): """Returns a list or substring made of the first v1 items of a list or string (respectively) at v2.""" if not inc.VAL(E,1) or not inc.listlike(E,2): print("Input Error: tailn") print(intf_TAILN.__doc__) return # Without doing much of anything. n= int(E.The.StackPop().val) # Position. ob2= E.The.StackPop() # List or text. if ob2.whatami == "TXT": out= objectifier.StackOB_TXT( ob2.val[-n:] ) else: out= objectifier.StackOB_LST( ob2.val[-n:] ) E.The.StackPush(out)
def build_GG_command(commandtext): """This function takes GeoGad program as a stream of text and parses it and forms it into activated lists of objects so that if the resulting object is called, it is executed macro style. This allows for the creation of built-in commands in both direct Python (the normal way) and in GeoGad itself (using this function).""" import objectifier import tokenizer CT = tokenizer.Tokenizer() # Set up a Command Tokenizer. CT.tokenize_input(commandtext) # Do it. buildinglist = list() # Temp construction list. for token in CT.get_token_queue(): buildinglist.append(objectifier.objectify(token)) command_object = objectifier.StackOB_LST(buildinglist) command_object.dead = False return command_object
def intf_MMTEST(E): """Simple test of the creation of a mm function. Get rid of this when everything is working fine.""" macro= "10 10 0 p dup 100 10 0 p dup rot l drop 50 100 0 p dup rot l drop l drop" oblistcontent= list() for s in macro.split(' '): try: s= float(s) except ValueError: pass if type(s) == type('str'): oblistcontent.append(objectifier.StackOB_SYM(s)) else: oblistcontent.append(objectifier.StackOB_VAL(s)) testmacro= objectifier.StackOB_LST(oblistcontent) testmacro.dead= False E.The.StackPush(testmacro)
def intf_NAMES(E): """Takes a list or SYM of a list from v1 and if that list has a name component, they are extracted into a separate list as TXT objects. This can be used with `repl` and `decorate` to change the naming of items in a list. [100 .9784 .8591 .5798::jpy usd franc pound] |money sto |money money names 3 [''chf'' ''gbp''] repl decorate money -> [100 .9784 .8591 .5798::jpy usd chf gbp] """ if not inc.listlike(E,1): print("Input Error: names") print(intf_NAMES.__doc__) return # Without doing much of anything. lstob= E.The.StackPop() # List item. if lstob.whatami == "SYM": symkey= lstob.val lstob= E.symtab[symkey] if lstob.whatami == "LST": namelist= map(lambda x: objectifier.StackOB_TXT(x) , lstob.names) E.The.StackPush( objectifier.StackOB_LST(namelist))
def intf_SORT(E): """Takes a LST object from v1 and returns a LST object where the components of v1 are sorted in ascending order. The items should all be TXT or VAL and of the same kind.""" # Python text sorting= `''.join(sorted([n for n in s]))` # Check out MIN and MAX to see how to resolve SYM objects. Not done here yet. if not inc.listlike(E,1): print("Input Error: sort") print(intf_SORT.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # List or text. if ob1.whatami == "TXT": out= objectifier.StackOB_TXT( ''.join(sorted([n for n in ob1.val])) ) else: if ob1.val and len(ob1.val) > 0: sortedvals= sorted([x.val for x in ob1.val]) sortedvals= [objectifier.StackOB_VAL(x) for x in sortedvals] out= objectifier.StackOB_LST( sortedvals ) else: out= ob1 E.The.StackPush(out)
def intf_REVLIST(E): """Takes a LST object from v1 and returns a LST object where the components of v1 are reversed in order. This allows for a descending sort with `sort reverse`.""" # Python text sorting= `''.join(sorted([n for n in s]))` if not inc.listlike(E,1): print("Input Error: revlist") print(intf_REVLIST.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # List or text. if ob1.whatami == "TXT": out= objectifier.StackOB_TXT( ob1.val[::-1] ) else: if ob1.val and len(ob1.val) > 0: #revedvals= [x.val for x in ob1.val] revedvals= ob1.val[:] revedvals.reverse() out= objectifier.StackOB_LST( revedvals) else: out= ob1 E.The.StackPush(out)
def intf_TAGNOTQUERY(E): """From level one, a TXT object or a list of TXT objects is taken off the stack. The entities which are NOT tagged with all the specified text items are returned in a list. An empty list is returned if no entities are tagged with the supplied tags. ''mytag'' nottag? -> [<entID> <entID>] [''mytag1'' ''mytag2''] nottag? -> [<entID> <entID] This will find any entities tagged with neither "roof" nor "house". [''roof'' ''house''] nottag? -> [<entID> <entID>] Actually right now it will find entities not tagged with *both* "roof" and "house". """ if not inc.TXT_or_LST_of_TXTs(E.The,1): print("Input Error: nottag?") print(intf_TAGNOTQUERY.__doc__) return # Without doing much of anything. mytags= E.The.StackPop().val if type(mytags)==type(list()): #mytags= map(lambda x:x.val, mytags) # Should now be a list of TXTs. mytags= [x.val for x in mytags] # Should now be a list of TXTs. else: mytags= [ mytags ] # Also a (1 item) list of ints. disqualifying_ents= list() for myeid in MMEL.El.keys(): atagishere= False # Assume they're here until one is not found. for mytag in mytags: #print("Searching entity #%d for tag ''%s''" % (myeid,mytag)) if MMEL.El[myeid].has_tag(mytag): atagishere= True break if atagishere: disqualifying_ents.append( myeid ) qualifying_ents= list() # For inverting. for myeid in MMEL.El.keys(): # Go through all ents again. if myeid not in disqualifying_ents: # Add ones not found before. qualifying_ents.append(myeid) # Objectify remaining. qualifying_ents= [objectifier.StackOB_VAL(m) for m in qualifying_ents] E.The.StackPush( objectifier.StackOB_LST(qualifying_ents) )
def intf_REPL(E): """Takes a string or list object from v3 and a position from v2 and a replacement string or list object from v1 and replaces the portion of v3 starting at v2 with v1. If v2 is less than 1 or greater than the `len` of v3, the items are simply concatenated, v1+v3 and v3+v1 respectively. [5 10 16 21 25] 3 [15 20] -> [5 10 15 20 25] ''abcdefghi'' 4 ''XYZ'' repl -> ''abcXYZghi'' """ if ( ( not inc.VAL(E,2) or not inc.listlike(E,1) or not inc.listlike(E,3) ) or ( inc.TXT(E,1) != inc.TXT(E,3) ) ): # If types don't match. print("Input Error: repl") print(intf_REPL.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # Replacement text or list n= int(E.The.StackPop().val) # Position. ob3ob= E.The.StackPop() # Original list or text. outistxt= (ob3ob.val == "TXT") oblen= len(ob3ob.val) if oblen < n: ob3= ob3ob.val+ob1.val elif n < 1: ob3= ob1.val+ob3ob.val else: n-= 1 if outistxt: ob3= list(ob3ob.val) # Python strings are immutable. else: ob3= ob3ob.val start= ob3ob.val[0:n] plusmid= start + ob1.val ob3= plusmid if len(plusmid) < oblen: ob3+= ob3ob.val[len(plusmid):] if outistxt: outob= objectifier.StackOB_TXT( ''.join(plusmid) ) else: outob= objectifier.StackOB_LST( ob3 ) E.The.StackPush(outob)
def intf_UNDO(E): """This function corrects the latest command, except undo itself, that was not undone. To undo the undo command itself, see redo. """ #print("Diagnostic in intf_UNDO - Before-UNDO Stack:") #E.Undo.StackDisplay() #print("Diagnostic in intf_UNDO - Before-REDO Stack:") #E.Redo.StackDisplay() if not E.Undo.StackIsEmpty(): Ucommand= objectifier.StackOB_LST(E.Undo.StackPop()) Ucommand.dead= False if E.redoing_now: # Redone commands must be reverse orderd. print("Problems here?") #Ucommand.val.reverse() # This is odd, but how it is. E.Undo, E.Redo= E.Redo, E.Undo # Cool! When undoing, the undo is redo. E.evaluate(Ucommand) E.Undo, E.Redo= E.Redo, E.Undo # Ok, now put it back. else: print("There is nothing to undo!") print("Diagnostic in intf_UNDO - After-UNDO Stack:") E.Undo.StackDisplay() print("Diagnostic in intf_UNDO - After-REDO Stack:") E.Redo.StackDisplay()
def intf_MIDN(E): """Given two points (LSTs of three VALs) on stack level 3 and 2 followed by a ratio N on level 1, compute the point on the line between the two supplied points N times the distance along the line. For example: [1 1 1] [6 11 16] .2 midn -> [2 3 4] Setting N to .5 returns the midpoint. This function can also extrapolate the supplied line as in: [0 0 0] [5 10 15] 2 midn -> [10 20 30] To get the midpoint of a line use something like: <entID> pts .5 midn Or use the built in alias for that: <entID> pts mid """ inputok= False if E.The.StackSize() >= 3: # Ensure something is here. checkob= E.The.StackCopyItemLast() if checkob.whatami == "VAL": inputok= True if not inputok or not inc.point_formatted_LST(E.The,2) or not inc.point_formatted_LST(E.The,3): print("Input Error: midn") print(intf_MIDN.__doc__) return # Without doing much of anything. ratio= E.The.StackPop().val P1object= E.The.StackPop() #P1= map(lambda x:x.val, P1object.val) # Should now be a list of floats. P1= [x.val for x in P1object.val] # Should now be a list of floats. P0object= E.The.StackPop() #P0= map(lambda x:x.val, P0object.val) # Should now be a list of floats. P0= [x.val for x in P0object.val] # Should now be a list of floats. x= (P1[0]-P0[0]) * ratio + P0[0] y= (P1[1]-P0[1]) * ratio + P0[1] z= (P1[2]-P0[2]) * ratio + P0[2] z= objectifier.StackOB_VAL(z) # Can't be just regular Python ints. y= objectifier.StackOB_VAL(y) x= objectifier.StackOB_VAL(x) p= objectifier.StackOB_LST([x, y, z]) p.names= ['x','y','z'] E.The.StackPush(p)
def intf_GET(E): """Returns from v2 LST object the value of the list component whose position is specified by v1. `[1.1 2.2 3.3 4.4] 3 get -> 3.3` See GETN for specifying position by list name. """ if not inc.VAL(E,1) or not inc.listlike(E,2): print("Input Error: get") print(intf_GET.__doc__) return # Without doing much of anything. n= int(E.The.StackPop().val) # Position. ob2= E.The.StackPop() # List or text. oblen= len(ob2.val) if oblen < n: n= oblen-1 elif n < 1: n= 0 else: n-= 1 if ob2.whatami == "TXT": out= objectifier.StackOB_TXT( ob2.val[n] ) else: out= objectifier.StackOB_LST( ob2.val[n] ) E.The.StackPush(out)
def intf_SUB(E): """Substring or sublist. Takes a string or list object from v3 and a start position from v2 and an end position from v1 and returns the sub-string or sub-list (respectively) from v2 to v1. If v1 is less than v2, an empty string or list is returned. Any positional value less than 1 is treated as 1. Any positional value greater than the `len` of v3 will be treated as the `len` of v3. The positional values are inclusive such that if v2 is 2 and v3 is 4, both the 2nd (and 3rd) and 4th position items will be part of the returned sub-object. ''abcdefghijklmnopqrstuvwxyz'' 19 21 sub -> ''stu'' """ if not inc.VAL(E,1) or not inc.VAL(E,2) or not inc.listlike(E,3): print("Input Error: sub") print(intf_SUB.__doc__) return # Without doing much of anything. n2= int(E.The.StackPop().val) # End position. n1= int(E.The.StackPop().val) # Start position. ob3= E.The.StackPop() # List or text. oblen= len(ob3.val) if oblen < n1: n1= oblen-1 elif n1 < 1: n1= 0 else: n1-= 1 if oblen < n2: n2= oblen elif n2 < 1: n2= 0 else: pass # Ok. out= ob3.val[n1:n2] if ob3.whatami == "LST": out= objectifier.StackOB_LST( out ) elif ob3.whatami == "TXT": out= objectifier.StackOB_TXT( out ) E.The.StackPush(out)
def put_user_settings_in_a_var(self, E): fi = objectifier.StackOB_TXT(self.outfile) ca = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.camera[0]), objectifier.StackOB_VAL(self.camera[1]), objectifier.StackOB_VAL(self.camera[2]) ]) ca.names = ['x', 'y', 'z'] ta = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.target[0]), objectifier.StackOB_VAL(self.target[1]), objectifier.StackOB_VAL(self.target[2]) ]) ta.names = ['x', 'y', 'z'] op = objectifier.StackOB_VAL(self.opacity) fl = objectifier.StackOB_VAL(self.facelines) lw = objectifier.StackOB_VAL(self.vlinewidth) ms = objectifier.StackOB_VAL(self.vrefreshms) bx = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.vboxX), objectifier.StackOB_VAL(self.vboxY) ]) bx.names = ['x', 'y'] tr = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.vtranX), objectifier.StackOB_VAL(self.vtranY) ]) tr.names = ['x', 'y'] sc = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.vscaleX), objectifier.StackOB_VAL(self.vscaleY) ]) sc.names = ['x', 'y'] vw = objectifier.StackOB_LST([fi, ca, ta, op, fl, lw, ms, bx, tr, sc]) vw.names = ['fi', 'ca', 'ta', 'op', 'fl', 'lw', 'ms', 'bx', 'tr', 'sc'] E.symtab['vw'] = vw
def intf_DIV(E): """Floating point division. Watch that div by zero!""" orig_den = E.The.StackPop() # Preserve in case of badness. orig_num = E.The.StackPop() # Preserve in case of badness. if (orig_den.whatami == 'TXT' or orig_num.whatami == 'TXT'): # Refuse text. print('Can not divide text.') E.The.StackPush(orig_num) # Run away! E.The.StackPush(orig_den) # Run away! return elif (orig_den.whatami == 'VAL' and orig_num.whatami == 'LST'): # Numbers/a list. outlist = list() for i in orig_num.val: if i.whatami == 'SYM': i = E.resolve_symbol(i) if i.whatami == 'TXT': i.val = 0 try: outlist.append(objectifier.StackOB_VAL(i.val / orig_den.val)) except ZeroDivisionError: print('n/0 - Oldest trick in the book!') E.The.StackPush(orig_num) # Run away! E.The.StackPush(orig_den) # Run away! return outlistob = objectifier.StackOB_LST(outlist) outlistob.names = orig_num.names[:] E.The.StackPush(outlistob) elif (orig_den.whatami == 'LST' and orig_num.whatami == 'VAL'): # A list/numbers. outlist = list() for po, i in enumerate(orig_den.val): if i.whatami == 'SYM': i = E.resolve_symbol(i) if i.whatami == 'TXT': i.val = 0 # Treat text as div by 0. try: outlist.append(objectifier.StackOB_VAL(orig_num.val / i.val)) except ZeroDivisionError: print('n/0 at position %d - Oldest trick in the book!' % po) E.The.StackPush(orig_den) # Run away! E.The.StackPush(orig_num) # Run away! return outlistob = objectifier.StackOB_LST(outlist) outlistob.names = orig_den.names[:] E.The.StackPush(outlistob) elif (orig_den.whatami == 'LST' and orig_num.whatami == 'LST'): # A list/B list. outlist = list() for po, i in enumerate(orig_den.val): j = orig_num.val[po] if i.whatami == 'SYM': i = E.resolve_symbol(i) if j.whatami == 'SYM': j = E.resolve_symbol(j) if i.whatami == 'TXT': i.val = 0 # Treat text as div by 0. if j.whatami == 'TXT': j.val = 0 # Treat text as div by 0. try: outlist.append(objectifier.StackOB_VAL(j.val / i.val)) except ZeroDivisionError: print('n/0 at position %d - Oldest trick in the book!' % po) E.The.StackPush(orig_den) # Run away! E.The.StackPush(orig_num) # Run away! return outlistob = objectifier.StackOB_LST(outlist) outlistob.names = orig_den.names[:] E.The.StackPush(outlistob) else: # Regular two value division. try: E.The.StackPush( objectifier.StackOB_VAL(orig_num.val / orig_den.val)) E.Undo.StackPush( [objectifier.StackOB_SYM('drop'), orig_num, orig_den]) except ZeroDivisionError: print('n/0 - Oldest trick in the book!') E.The.StackPush(orig_num) # Run away! E.The.StackPush(orig_den) # Run away!
def intf_MUL(E): """Item multiplication operator where the values are the focus. Compare to `:*` where lists are the focus. Valid inputs: SYM SYM + -> (resolve any SYMs and proceed again) VAL VAL * -> simple multiplication TXT VAL * -> replication of text into concatenated text, commutative input LST_of_VALs VAL * -> list of each list item multiplied by VAL, commutative input LST_of_VALs LST_of_VALs * -> pad smaller with 1 and multiply each ith pos If two lists are multiplied, the shorter one is padded with ones to match the other. In the case of two lists and both have list names, the longest list's are used. Examples: 2 2 * -> 4 2 [1 2 3] * -> [2 4 6] 31.831 |diameter sto |diameter |pi * -> 100.000035756 [pi pi pi] pi inv * -> [1 1 1] [1 2 3] 2 * -> [2 4 6] [1 2 3] [1 2] * -> [1 4 3] Pad the shorter list with ones. [2 2] [4 4 4::x y z] * -> [8 8 4]<x y z> [1 2] [1 2 3] * -> [1 4 3] 4 ''ha'' * -> ''hahahaha'' ''backwards'' -2 * -> ''sdrawkcabsdrawkcab'' """ if not ((inc.TXT(E, 1) and inc.VAL(E, 2)) or (inc.VAL(E, 1) and inc.TXT(E, 2)) or ((inc.VAL(E, 1) or inc.LST_of_VALs(E, 1)) and (inc.VAL(E, 2) or inc.LST_of_VALs(E, 2)))): print("Input Error: mul") print(intf_MUL.__doc__) return # Without doing much of anything. v2 = E.resolve_symbol(E.The.StackPop()) v1 = E.resolve_symbol(E.The.StackPop()) if v1.whatami == 'VAL' and v2.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(v1.val * v2.val)) elif v1.whatami == "TXT": if v2.val < 0: v1.val, v2.val = v1.val[::-1], v2.val * -1 # Do this for `neg`. E.The.StackPush(objectifier.StackOB_TXT(v1.val * int(v2.val))) elif v2.whatami == "TXT": if v1.val < 0: v2.val, v1.val = v2.val[::-1], v1.val * -1 # It's silly, I know. E.The.StackPush(objectifier.StackOB_TXT(v2.val * int(v1.val))) elif ((v1.whatami == 'LST' and v2.whatami == 'VAL') or (v1.whatami == 'VAL' and v2.whatami == 'LST')): # Mixed LST&VAL if v1.whatami == 'VAL': v1, v2 = v2, v1 # Ensure LST 1st then VAL 2nd outlist = list() for i in v1.val: if i.whatami == 'SYM': i = E.resolve_symbol(i) outlist.append(objectifier.StackOB_VAL(i.val * v2.val)) outlistob = objectifier.StackOB_LST(outlist) outlistob.names = v1.names[:] E.The.StackPush(outlistob) elif v1.whatami == 'LST' and v2.whatami == 'LST': lv1, lv2 = len(v1.val), len(v2.val) if lv1 < lv2: v1, v2 = v2, v1 # Longest LST first. lv1, lv2 = lv2, lv1 outlist = list() for n, i in enumerate(v1.val): if i.whatami == 'SYM': i = E.resolve_symbol(i) if n < lv2: if v2.val[n].whatami == 'SYM': froml2 = E.resolve_symbol(i) else: froml2 = v2.val[n] outlist.append(objectifier.StackOB_VAL(i.val * froml2.val)) else: outlist.append(objectifier.StackOB_VAL(i.val)) outlistob = objectifier.StackOB_LST(outlist) if not v1.names and v2.names: # If both have names go with v1's. v1, v2 = v2, v1 outlistob.names = v1.names[:] E.The.StackPush(outlistob) else: print( "Error: What the hell have you done!? This should never have happend. See `intf_MUL`." ) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), v2, v1])
def intf_ADD(E): """Item addition operator where the values are the focus. Compare to `:+` where lists are the focus. All SYMs are resolved. Valid inputs: TXT TXT + -> concatenate text VAL VAL + -> simple addition, commutative LST_of_VALs VAL + -> add VAL to all items in list (of values), commutative LST_of_VALs LST_of_VALs + -> pad smaller with zero and add each ith pos, commutative If two lists are added, the shorter one is padded with zeros to match the other. In the case of two lists and both have list names, the longest list's are used. Examples: 2 2 + -> 4 |pi pi + 2deg -> 360 [pi 10::a b] |Q sto -180 2rad Q.a + -> 0 [4 8] 3 + -> [7 11] [4 8] [2 3] + -> [6 11] [4 8] [2 3] + -> [6 11] [4 8 3] [2 3] + -> [6 11 3] [4 8] [1 2 3] + -> [5 10 3] [0 4] [1 2 3] + -> [1 6 3] [1 2 3::a b c] [2 2 2::x y z] + -> [3 4 5]<a b c> ''xed'' ''.ch'' + -> ''xed.ch'' """ if not ((inc.TXT(E, 1) and inc.TXT(E, 2)) or ((inc.VAL(E, 1) or inc.LST_of_VALs(E, 1)) and (inc.VAL(E, 2) or inc.LST_of_VALs(E, 2)))): print("Input Error: add") print(inc.LST_of_VALs(E, 1)) print(inc.LST_of_VALs(E, 2)) print(" Value 1:" + str(E.The.StackPop())) print(" Value 2:" + str(E.The.StackPop())) print(intf_ADD.__doc__) return # Without doing much of anything. v2 = E.resolve_symbol(E.The.StackPop()) v1 = E.resolve_symbol(E.The.StackPop()) if v1.whatami == 'TXT': # v2's been checked. E.The.StackPush(objectifier.StackOB_TXT(v1.val + v2.val)) elif v1.whatami == 'VAL' and v2.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(v1.val + v2.val)) elif ((v1.whatami == 'LST' and v2.whatami == 'VAL') or (v1.whatami == 'VAL' and v2.whatami == 'LST')): # Mixed LST&VAL if v1.whatami == 'VAL': v1, v2 = v2, v1 # Ensure LST 1st then VAL 2nd outlist = list() for i in v1.val: if i.whatami == 'SYM': i = E.resolve_symbol(i) outlist.append(objectifier.StackOB_VAL(i.val + v2.val)) outlistob = objectifier.StackOB_LST(outlist) outlistob.names = v1.names[:] E.The.StackPush(outlistob) elif v1.whatami == 'LST' and v2.whatami == 'LST': lv1, lv2 = len(v1.val), len(v2.val) if lv1 < lv2: v1, v2 = v2, v1 # Longest LST first. lv1, lv2 = lv2, lv1 outlist = list() for n, i in enumerate(v1.val): if i.whatami == 'SYM': i = E.resolve_symbol(i) if n < lv2: if v2.val[n].whatami == 'SYM': froml2 = E.resolve_symbol(i) else: froml2 = v2.val[n] outlist.append(objectifier.StackOB_VAL(i.val + froml2.val)) else: outlist.append(objectifier.StackOB_VAL(i.val)) outlistob = objectifier.StackOB_LST(outlist) if not v1.names and v2.names: # If both have names go with v1's. v1, v2 = v2, v1 outlistob.names = v1.names[:] E.The.StackPush(outlistob) else: print( "Error: What the hell have you done!? This should never have happend. See `intf_ADD`." ) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), v2, v1])