how to approach converting VBscript to Python code? - python

I've been asked by my boss to convert a piece of vb script, which is manually run every Friday into python, except he wants it automated. I'm new to programming and would like some help deciding how to begin with this problem. This will be my first real programming project and fortunatley there is no real time restriction.
Context: We have an ESRI Flexviewer for displaying maps in our organisation. The script in question takes polylines, calculates the angle of the line, then calculates the flow direction. It does this by using a to and from field within the polylines feature class and places direction arrows on the mid point of each pipe.
I've pasted the script below... its kind of long but any help would be much appreciated!
So what I'm asking for is a suggestion on how to attack this. Just a start. Do i list out the main processes the VB script is using? Do i draw a flow diagram and being writing out psydo code for python? should i identify the main processes, for example the loops? and use that as a framework to begin?
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.Catalog
Imports ESRI.ArcGIS.CatalogUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.SystemUI
Imports System.Windows
<ComClass(CmdFlowCreation.ClassId, CmdFlowCreation.InterfaceId, CmdFlowCreation.EventsId), _
ProgId("FlowArrows.CmdFlowCreation")> _
Public NotInheritable Class CmdFlowCreation
Inherits BaseCommand
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "35ac8cdc-4893-42d5-97ad-f41804dcb618"
Public Const InterfaceId As String = "ec8ac176-19cc-4979-a5ca-4f7cf80bb37b"
Public Const EventsId As String = "af685c91-ec0a-4ccd-ad21-56f9811c5f72"
#End Region
#Region "COM Registration Function(s)"
<ComRegisterFunction(), ComVisibleAttribute(False)> _
Public Shared Sub RegisterFunction(ByVal registerType As Type)
' Required for ArcGIS Component Category Registrar support
ArcGISCategoryRegistration(registerType)
'Add any COM registration code after the ArcGISCategoryRegistration() call
End Sub
<ComUnregisterFunction(), ComVisibleAttribute(False)> _
Public Shared Sub UnregisterFunction(ByVal registerType As Type)
' Required for ArcGIS Component Category Registrar support
ArcGISCategoryUnregistration(registerType)
'Add any COM unregistration code after the ArcGISCategoryUnregistration() call
End Sub
#Region "ArcGIS Component Category Registrar generated code"
Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type)
Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
GxCommands.Register(regKey)
End Sub
Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type)
Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
GxCommands.Unregister(regKey)
End Sub
#End Region
#End Region
Private Const dDistance As Double = 0.5
Private Const bAsRatio As Boolean = True
Private m_application As IApplication
Dim pFClass As IFeatureClass
Public m_pPropertySet As ESRI.ArcGIS.esriSystem.IPropertySet 'SDE Connection Properties
Public m_pWS As IWorkspace
Public m_pWSF As IWorkspaceFactory
Public bContinue As Boolean
Public pLineLayer As IFeatureLayer
Public pPointLayer As IFeatureLayer
Public bCreate As Boolean
Public bUpdate As Boolean
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
' TODO: Define values for the public properties
MyBase.m_category = "PNCC ARCCatalog" 'localizable text
MyBase.m_caption = "Flow Creation" 'localizable text
MyBase.m_message = "Create flow arrows. 9.3" 'localizable text
MyBase.m_toolTip = "Flow Creation 9.3 (17-May-2010)" 'localizable text
MyBase.m_name = "FlowArrows.CmdFlowCreation" 'unique id, non-localizable (e.g. "MyCategory_ArcCatalogCommand")
Try
'TODO: change bitmap name if necessary
Dim bitmapResourceName As String = Me.GetType().Name + ".bmp"
' MyBase.m_bitmap = New Bitmap(Me.GetType(), bitmapResourceName)
MyBase.m_bitmap = Global.FlowArrows.My.Resources.BMPCmdFlowCreation
Catch ex As Exception
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap")
End Try
End Sub
'' Public ReadOnly Property Enabled() As Boolean Implements ESRI.ArcGIS.SystemUI.ICommand.Enabled
'' Dim mxDoc As IMxDocument
'' Dim layerCount As Integer
'' 'pApp is set in OnCreate
'' mxDoc = CType(m_pApp.Document, IMxDocument)
'' layerCount = mxDoc.FocusMap.LayerCount
'' If pLayerCount> 0 Then
'' Return True
'' Else
'' Return False
'' End If
'' End Property
'Private Property Get ICommand_Enabled() As Boolean
'ICommand_Enabled = True
'Dim pGxApplication As IGxApplication
'Dim pGxObject As IGxObject
'Dim pGxDataSet As IGxDataset
'Set pGxApplication = mApplication
'Set pGxObject = pGxApplication.SelectedObject
''
'If TypeOf pGxObject Is IGxDataset Then
' Set pGxDataSet = pGxObject
' If TypeOf pGxDataSet.Dataset Is IFeatureClass Then
'' Dim pFClass As IFeatureClass
' Set pFClass = pGxDataSet.Dataset
' If pFClass.ShapeType = esriGeometryPolyline Then
' ICommand_Enabled = True
' End If
' End If
'Else
' ICommand_Enabled = False
'End If
'End Property
Public Overrides Sub OnCreate(ByVal hook As Object)
If Not hook Is Nothing Then
m_application = CType(hook, IApplication)
'Disable if it is not ArcCatalog
If TypeOf hook Is IGxApplication Then
MyBase.m_enabled = True
Else
MyBase.m_enabled = False
End If
End If
' TODO: Add other initialization code
End Sub
Public Overrides Sub OnClick()
'TODO: Add CmdFlowCreation.OnClick implementation
Dim pLayer As ILayer
Dim pFeatLayer As IFeatureLayer
Dim pFeatClass As IFeatureClass
pLineLayer = New FeatureLayer
pFeatClass = GetArcCatalogSelectedLayer()
If pFeatClass Is Nothing Then
Exit Sub
End If
pLineLayer.FeatureClass = pFeatClass
''''MyBase.m_enabled = False
GetWSFactory()
PopulateLineAngle()
End Sub
Public Function GetArcCatalogSelectedLayer() As IFeatureClass
Dim arcCatalog As IGxApplication
arcCatalog = CType(m_application, IGxApplication)
'Get the Selected Object in Catalog
Dim catalogSelectedObject As ESRI.ArcGIS.Catalog.IGxObject = arcCatalog.SelectedObject
If (Not (TypeOf catalogSelectedObject Is ESRI.ArcGIS.Catalog.IGxDataset)) Then
System.Windows.Forms.MessageBox.Show("Must have feature dataset selected")
Return Nothing
End If
'Make sure it's a Feature Class
Dim catalogDataset As IGxDataset
catalogDataset = CType(catalogSelectedObject, IGxDataset)
If (catalogDataset.Type <> esriDatasetType.esriDTFeatureClass) Then
System.Windows.Forms.MessageBox.Show("Must have feature featureclass selected")
Return Nothing
End If
Dim featureClass As IFeatureClass
featureClass = CType(catalogDataset.Dataset, IFeatureClass)
If featureClass.ShapeType <> esriGeometryType.esriGeometryPolyline Then
System.Windows.Forms.MessageBox.Show("Must have a LINE type featureclass selected")
Return Nothing
End If
Return featureClass
End Function
Public Sub GetWSFactory()
On Error Resume Next
Dim pDataset As IDataset
Dim pWorkSpace As IWorkspace
pDataset = pLineLayer.FeatureClass
pWorkSpace = pDataset.Workspace
m_pPropertySet = pWorkSpace.ConnectionProperties
If Not m_pPropertySet Is Nothing Then
m_pWSF = New ESRI.ArcGIS.DataSourcesGDB.SdeWorkspaceFactory
m_pWS = m_pWSF.Open(m_pPropertySet, 0)
End If
End Sub
Private Sub PopulateLineAngle()
'get the center point of the line segment and populate the angle if the line
Dim str As String = ""
Try
Dim pQueryFilt As IQueryFilter
Dim pFeature As IFeature
Dim pFeatCur As IFeatureCursor
Dim pLnFeatClass As IFeatureClass
Dim pPtFeatClass As IFeatureClass
Dim pStatusBar As ESRI.ArcGIS.esriSystem.IStatusBar
Dim Pi As Double
Dim pCurve As ICurve
Dim pMiddlePoint As IPoint
Dim dAngle As Double
Dim pLine As ILine
Dim pTable As ITable
Dim dLength As Double
Dim lLnCompKeyFld As Long
Dim lLnCompTypeFld As Long
Dim lCompKeyFld As Long
Dim lAngleFld As Long
Dim lCompTypeFld As Long
Dim pNewFeat As IFeature
Dim pDS As IDataset
Dim lastOID As Integer = 0
pStatusBar = m_application.StatusBar
Pi = 4 * System.Math.Atan(1)
'-------- 1. Get the point layer ---------------
pPointLayer = GetPointLayer()
lastOID = GetLastOID(pPointLayer.FeatureClass)
If pPointLayer Is Nothing Then
' MsgBox "The Update point layer does not exist!", vbCritical, "Process Halted"
Exit Sub
End If
'-------- 2. populate update fields index ----------
pPtFeatClass = pPointLayer.FeatureClass
lCompKeyFld = pPtFeatClass.FindField("CompKey")
lAngleFld = pPtFeatClass.FindField("Angle")
lCompTypeFld = pPtFeatClass.FindField("CompType")
pLnFeatClass = pLineLayer.FeatureClass
lLnCompKeyFld = pLnFeatClass.FindField("Compkey")
lLnCompTypeFld = pLnFeatClass.FindField("CompType")
'--------- 3. populate the angle for all the features in the line layer ----
''''pQueryFilt = New QueryFilter
''''pFeatCur = pLnFeatClass.Search(pQueryFilt, False)
pQueryFilt = New QueryFilter
''''''
pTable = CType(pLnFeatClass, ITable)
Dim tableSort As ITableSort = New TableSortClass()
tableSort.Table = pTable
tableSort.QueryFilter = pQueryFilt
tableSort.Fields = "OBJECTID"
pLnFeatClass = CType(pTable, IFeatureClass)
pFeatCur = pLnFeatClass.Search(pQueryFilt, False)
''''''
pFeature = pFeatCur.NextFeature
Dim iCnt As Integer = 0
Dim pWorkspaceEdit As ITransactions
pWorkspaceEdit = m_pWS
pWorkspaceEdit.StartTransaction()
Do While Not pFeature Is Nothing And iCnt < lastOID 'Loop through existing features.
iCnt += 1
pStatusBar.Message(0) = "Finding .... feature:" & pFeature.OID & " - " & iCnt.ToString
pFeature = pFeatCur.NextFeature
System.Windows.Forms.Application.DoEvents()
Loop
Do While Not pFeature Is Nothing
iCnt += 1
pStatusBar.Message(0) = "Calculating .... feature:" & pFeature.OID & " - " & iCnt.ToString
pCurve = pFeature.Shape
dLength = pCurve.Length
pMiddlePoint = New ESRI.ArcGIS.Geometry.Point
'get the middle point
pCurve.QueryPoint(esriSegmentExtension.esriNoExtension, dDistance, bAsRatio, pMiddlePoint)
'get the angle
pLine = New ESRI.ArcGIS.Geometry.Line
pCurve.QueryTangent(esriSegmentExtension.esriNoExtension, dDistance, bAsRatio, dLength, pLine)
dAngle = pLine.Angle * 360 / (2 * Pi)
dAngle = 270 + dAngle
' If dAngle < 90 Then
' dAngle = 90 - dAngle
' Else
' dAngle = 450 - dAngle
' End If
'add to point layer
pNewFeat = pPtFeatClass.CreateFeature
pNewFeat.Shape = pMiddlePoint
If lAngleFld <> -1 Then pNewFeat.Value(lAngleFld) = CLng(dAngle)
If lCompKeyFld <> -1 And lLnCompKeyFld <> -1 Then
pNewFeat.Value(lCompKeyFld) = pFeature.Value(lLnCompKeyFld)
End If
If lCompTypeFld <> -1 And lLnCompTypeFld <> -1 Then
pNewFeat.Value(lCompTypeFld) = pFeature.Value(lLnCompTypeFld)
End If
pNewFeat.Store()
pWorkspaceEdit.CommitTransaction()
pFeature = pFeatCur.NextFeature
If iCnt Mod 100 = 0 Then
System.Windows.Forms.Application.DoEvents()
End If
Loop
pStatusBar.Message(0) = "Finished!"
Catch ex As Exception
MsgBox(ex.Message + " - " + str)
m_application.StatusBar.Message(0) = "Finished with errors!"
End Try
End Sub
Private Function GetLastOID(ByVal pFClass As IFeatureClass) As Integer
'sde workspace open start a transaction to rollback if any error occurs
On Error Resume Next
Dim pWorkspaceEdit As ITransactions
pWorkspaceEdit = m_pWS
'' pWorkspaceEdit.StartTransaction()
' 'delete feature class records
'
Dim pFeatCursor As IFeatureCursor
Dim pFeature As IFeature
pFeatCursor = pFClass.Update(Nothing, False)
pFeature = pFeatCursor.NextFeature
Dim OID As Integer = 0
'
Do While pFeature Is Nothing = False
OID = pFeature.OID
pFeature = pFeatCursor.NextFeature
Loop
If OID > 0 Then '' Delete the last one, it might have been corrupted
Dim qFilter As IQueryFilter
qFilter = New QueryFilter
qFilter.WhereClause = "OBJECTID = " & OID.ToString
pFeatCursor = pFClass.Update(qFilter, False)
pFeature = pFeatCursor.NextFeature
pFeatCursor.DeleteFeature()
OID = OID - 1
End If
Return OID
End Function
Private Function GetPointLayer() As ILayer
On Error GoTo eh
Dim pFWS As IFeatureWorkspace
pFWS = m_pWS
Dim sNewFCName As String
Dim sFCName As String
sFCName = GetFeatureClassName(pLineLayer)
sNewFCName = sFCName & "_FLOW_UPDATE"
' ' Get the feature class
Dim pFeatureClass As IFeatureClass
pFeatureClass = pFWS.OpenFeatureClass(sNewFCName)
If pFeatureClass Is Nothing Then 'not exits
MsgBox("The feature class : " & sNewFCName & " does not exist, please create it first then run the tool again.")
GoTo eh
Else
''AK dont delete features. Will find the last and continue from there.
''''DeleteFeatures(pFeatureClass)
'already exists, delete all the features
' Dim pDS As IDataset
' Set pDS = pFeatureClass
' pDS.Delete
'
' Set pFeatureClass = CreateFeatureClass(sNewFCName)
End If
Dim pFeatureLayer As IFeatureLayer
pFeatureLayer = New FeatureLayer
pFeatureLayer.FeatureClass = pFeatureClass
GetPointLayer = pFeatureLayer
Exit Function
eh:
GetPointLayer = Nothing
End Function
Public Function GetFeatureClassName(ByVal pFeatLayer As IFeatureLayer) As String
Dim pDataset As IDataset
pDataset = pFeatLayer.FeatureClass
GetFeatureClassName = pDataset.Name
End Function
Private Sub DeleteFeatures(ByVal pFClass As IFeatureClass)
'sde workspace open start a transaction to rollback if any error occurs
On Error Resume Next
Dim pWorkspaceEdit As ITransactions
pWorkspaceEdit = m_pWS
pWorkspaceEdit.StartTransaction()
' 'delete feature class records
'
' Dim pFeatCursor As IFeatureCursor
' Dim pFeature As IFeature
' Set pFeatCursor = pFClass.Update(Nothing, False)
' Set pFeature = pFeatCursor.NextFeature
'
' Do While pFeature Is Nothing = False
' pFeatCursor.DeleteFeature
' Set pFeature = pFeatCursor.NextFeature
' Loop
Dim pFeatureWorkspace As IFeatureWorkspace
pFeatureWorkspace = pWorkspaceEdit
Dim t As ITable
t = pFeatureWorkspace.OpenTable(pFClass.AliasName)
t.DeleteSearchedRows(Nothing)
pWorkspaceEdit.CommitTransaction()
End Sub
End Class

Draw a flow diagram of the code; then translate that into pseudo code. Define the main variables ("containers") that you want to keep your data in. What is their relationship. Do some of them change while others are constant? Are there arrays of data?
Thinking about these things up front will really help you write clean code. And you will start your programming journey in the right direction. Most people would just start writing code.
I commend you for taking the time to ask this question. Good luck.

Related

PyParsing: parse if not a keyword

I am trying to parse a file as follows:
testp.txt
title = Test Suite A;
timeout = 10000
exp_delay = 500;
log = TRUE;
sect
{
type = typeA;
name = "HelloWorld";
output_log = "c:\test\out.log";
};
sect
{
name = "GoodbyeAll";
type = typeB;
comm1_req = 0xDEADBEEF;
comm1_resp = (int, 1234366);
};
The file first contains a section with parameters and then some sects. I can parse a file containing just parameters and I can parse a file just containing sects but I can't parse both.
from pyparsing import *
from pathlib import Path
command_req = Word(alphanums)
command_resp = "(" + delimitedList(Word(alphanums)) + ")"
kW = Word(alphas+'_', alphanums+'_') | command_req | command_resp
keyName = ~Literal("sect") + Word(alphas+'_', alphanums+'_') + FollowedBy("=")
keyValue = dblQuotedString.setParseAction( removeQuotes ) | OneOrMore(kW,stopOn=LineEnd())
param = dictOf(keyName, Suppress("=")+keyValue+Optional(Suppress(";")))
node = Group(Literal("sect") + Literal("{") + OneOrMore(param) + Literal("};"))
final = OneOrMore(node) | OneOrMore(param)
param.setDebug()
p = Path(__file__).with_name("testp.txt")
with open(p) as f:
try:
x = final.parseFile(f, parseAll=True)
print(x)
print("...")
dx = x.asDict()
print(dx)
except ParseException as pe:
print(pe)
The issue I have is that param matches against sect so it expects a =. So I tried putting in ~Literal("sect") in keyName but that just leads to another error:
Exception raised:Found unwanted token, "sect", found '\n' (at char 188), (line:4, col:56)
Expected end of text, found 's' (at char 190), (line:6, col:1)
How do I get it use one parse method for sect and another (param) if not sect?
My final goal would be to have the whole lot in a Dict with the global params and sects included.
EDIT
Think I've figured it out:
This line...
final = OneOrMore(node) | OneOrMore(param)
...should be:
final = ZeroOrMore(param) + ZeroOrMore(node)
But I wonder if there is a more structured way (as I'd ultimately like a dict)?

Tiny Language compiler using python and regex

Hello stack overflow users
I hope you having a good
so I'm doing this tiny language compiler for my homework
tried using regex
but the output is so weird
First of all, I get an Identifier called 't' which is not used in my input
And it doesn't separate Identifier 'x' from the semicolon
thanks in advance for your help
Here is my input
read x; {input an integer }
if 0 < x then { don’t compute if x <= 0 }
fact := 1;
repeat
fact := fact * x;
x := x - 1
until x = 0;
write fact { output factorial of x }
end
And that's my code using regex
# -*- coding: utf-8 -*-
"""
Created on Wed May 13 04:11:06 2020
#author: PC
"""
class OwnCompiler (object):
def __init__ (self,file):
import re
self.file=open(file,"r").readlines()
self.symbols = {
"+":"PLUS_OP",
"-":"MINUS_OP",
"*":"MUL_OP",
"/":"DIV_OP",
"=":"EQUAL_OP",
"<":"LESS_OP",
">":"GREATER_OP",
"(":"LEFT_PARENTHESIS",
")":"RIGHT_PARENTHESIS",
":=":"ASSIGN",
";":"SEMICOLON",
}
self.commentPattern = re.compile(r".*({\n*\s*.*\s*})")
self.reservePattern = re.compile(r"\s*(read|write|if|then|else|end|repeat|until)+\s*(.*)(then)*")
self.symbolPattern = re.compile(r".*(\+|\*|-|/|=|<|>|\(|\)|;)")
self.identifierSymbol = re.compile(r".*(\w+)\s+(:=)\s+(.*)")
def compileOutput(self):
self.fileWrite=open("output.txt","w")
self.fileWrite.write("Type Token\n==================\n")
for i in self.file :
print(i)
self.getComment(i)
self.getReserveWord(i)
self.getIdentify(i)
self.fileWrite.close()#end
def getComment(self,text):
try:
self.fileWrite.write("COMMENT "+self.commentPattern.match(text).group(1)+"\n")
except:
print("NO_COMMENT")
def getReserveWord(self,text):
self.Compiled = self.reservePattern.match(text)
try:
self.fileWrite.write("RESERVE_WORD "+self.Compiled.group(1)+"\n")
self.getSymbols(self.Compiled.group(2))
try:
self.fileWrite.write("RESERVE_WORD "+self.Compiled.group(3)+"\n")
except:
print("NO_RESERVE_WORD2")
except:
print("NO_RESERVE_WORD")
def getSymbols(self,text):
self.Compiled= self.symbolPattern.match(text)
self.GOT_TOKEN= self.getTokensSymbols(self.Compiled.group())
try:
self.fileWrite.write(self.GOT_TOKEN+" "+self.Compiled.group()+"\n")
except:
print("NO_SYMBOLS")
def getIdentify(self,text):
self.Compiled = self.identifierSymbol.match(text)
try:
self.fileWrite.write("IDENTIFIER "+self.Compiled.group(1)+"\n")
self.getSymbols(text)
for i in self.Compiled.group(3):
if i ==" " :
continue
if self.isNumber(i):
self.fileWrite.write("NUMBER ")
else:
self.fileWrite.write("WORD ")
self.fileWrite.write(self.Compiled.group(3)+"\n")
except:
print("NO_IDENTIFIRES")
def getTokensSymbols(self,symbol):
try:
return self.symbols[symbol]
except:
print("NOT_DEFINED_IN_SYMBOL_DICT")
return "UNKNOWN"
def isNumber(self,text):
try:
int(text)
return True
except:
return False
if __name__ == "__main__":
instance = OwnCompiler("input.txt")
instance.compileOutput()
And here is my output
Type Token
==================
COMMENT { Sample program in TINY language – computes factorial }
COMMENT {input an integer }
RESERVE_WORD read
UNKNOWN x;
COMMENT { don’t compute if x <= 0 }
RESERVE_WORD if
UNKNOWN 0 < x then { don’t compute if x <=
IDENTIFIER t
UNKNOWN fact := 1;
RESERVE_WORD repeat
IDENTIFIER t
UNKNOWN fact := fact * x;
IDENTIFIER x
UNKNOWN x := x -
RESERVE_WORD until
UNKNOWN x = 0;
COMMENT { output factorial of x }
RESERVE_WORD write
RESERVE_WORD end
If you are going to parse a language you need a 'lexer' that will return individual tokens ignoring whitespace and comments. Along these lines, just as an example:
import re, collections
class Lexer(object):
WHITESPACE = r'(?P<WHITESPACE>\s+)'
COMMENT = r'(?P<COMMENT>{[^}]*})'
READ = r'(?P<READ>\bread\b)'
WRITE = r'(?P<WRITE>\bwrite\b)'
IF = r'(?P<IF>\bif\b)'
THEN = r'(?P<THEN>\bthen\b)'
ELSE = r'(?P<ELSE>\belse\b)'
END = r'(?P<END>\bend\b)'
REPEAT = r'(?P<REPEAT>\brepeat\b)'
UNTIL = r'(?P<UNTIL>\buntil\b)'
OPERATOR = r'(?P<OPERATOR>(?:[+*/=<>-]|:=))'
LPAREN = r'(?P<LPAREN>\()'
RPAREN = r'(?P<RPAREN>\))'
IDENTIFIER = r'(?P<IDENTIFIER>[a-z]+)'
INTEGER = r'(?P<INTEGER>\d+)'
SEMICOLON = r'(?P<SEMICOLON>;)'
regex = re.compile('|'.join([
WHITESPACE,
COMMENT,
READ,
WRITE,
IF,
THEN,
ELSE,
END,
REPEAT,
UNTIL,
OPERATOR,
LPAREN,
RPAREN,
IDENTIFIER,
INTEGER,
SEMICOLON
]))
def __init__ (self, file):
def generate_tokens(text):
Token = collections.namedtuple('Token', ['type','value'])
scanner = Lexer.regex.finditer(text)
last_end = 0
for m in scanner:
start = m.start()
end = m.end()
if start != last_end:
# skipped over text to find the next token implies that there was unrecognizable text or an "error token"
text = self.text[last_end:start]
token = Token('ERROR', text)
yield token
last_end = end
token = Token(m.lastgroup, m.group())
if token.type != 'WHITESPACE' and token.type != 'COMMENT':
yield token
yield Token('EOF', '<end-of-file>')
with open(file, "r") as f:
text = f.read()
self._token_generator = generate_tokens(text)
def next_token(self):
# if you call this past the "EOF" token you will get a StopIteration exception
return self._token_generator.__next__()
lexer = Lexer('input.txt')
while True:
token = lexer.next_token()
print(token)
if token.type == 'EOF':
break
Prints:
Token(type='READ', value='read')
Token(type='IDENTIFIER', value='x')
Token(type='SEMICOLON', value=';')
Token(type='IF', value='if')
Token(type='INTEGER', value='0')
Token(type='OPERATOR', value='<')
Token(type='IDENTIFIER', value='x')
Token(type='THEN', value='then')
Token(type='IDENTIFIER', value='fact')
Token(type='OPERATOR', value=':=')
Token(type='INTEGER', value='1')
Token(type='SEMICOLON', value=';')
Token(type='REPEAT', value='repeat')
Token(type='IDENTIFIER', value='fact')
Token(type='OPERATOR', value=':=')
Token(type='IDENTIFIER', value='fact')
Token(type='OPERATOR', value='*')
Token(type='IDENTIFIER', value='x')
Token(type='SEMICOLON', value=';')
Token(type='IDENTIFIER', value='x')
Token(type='OPERATOR', value=':=')
Token(type='IDENTIFIER', value='x')
Token(type='OPERATOR', value='-')
Token(type='INTEGER', value='1')
Token(type='UNTIL', value='until')
Token(type='IDENTIFIER', value='x')
Token(type='OPERATOR', value='=')
Token(type='INTEGER', value='0')
Token(type='SEMICOLON', value=';')
Token(type='WRITE', value='write')
Token(type='IDENTIFIER', value='fact')
Token(type='END', value='end')
Token(type='EOF', value='<end-of-file>')

Can't get live output from python file to vb.net by ProcessStartInfo

Hi I know there is alot of the same question out here already but I tried every single one of them and can't seem to get why it won't work.
Here is my code
Private Sub CallbackProcessAsync(sender As Object, args As System.Diagnostics.DataReceivedEventArgs)
Console.WriteLine(args.Data)
Me.Invoke(Sub() statusRichText.AppendText(args.Data & Environment.NewLine))
End Sub
Sub SuperUpload()
Dim oProcess As New Process()
AddHandler oProcess.ErrorDataReceived, AddressOf CallbackProcessAsync
AddHandler oProcess.OutputDataReceived, AddressOf CallbackProcessAsync
Dim oStartInfo As New ProcessStartInfo("C:\Users\RKjetski\AppData\Local\Programs\Python\Python37\python.exe", "test.py " + vInfoIframe.Text + " " + vInfoID.Text)
oStartInfo.UseShellExecute = False
oStartInfo.CreateNoWindow = True
oStartInfo.RedirectStandardError = True
oStartInfo.RedirectStandardOutput = True
oProcess.EnableRaisingEvents = True
oProcess.StartInfo = oStartInfo
oProcess.Start()
oProcess.BeginErrorReadLine()
oProcess.BeginOutputReadLine()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnSuperUpload.Click
Dim thread = New System.Threading.Thread(AddressOf SuperUpload)
thread.Start()
End Sub
The python file
import time
x = 0
while x < 5:
print(x)
time.sleep(2)
x = x +1
I get the following output but it's not live / in real time, the rich text box is empty until it read the program and then it prints everything instantly.
0
1
2
3
4

Multiplex address and data to show string of letters over parallel port

A month ago, i asked this about multiplexing a string of numbers with 4 7-segment displays. But now, I'm trying to update the code to multiplex a string of letters using 7 7-segment displays in python.
This is the new circuit. When i send data using the parallel port, the Latch Enable receives the most significant bit (pin 9). In the second latch, the Latch Enable receives it also but negated, that is the reason of the 7404.
That is either address is set (/LE==False) or data is set (/LE=True).
This is what I'm trying to do. The 'X' represents that the 7-segment display is off. But can't archive it.
XXXXXXX
XXXXXXS
XXXXXST
XXXXSTA
XXXSTAC
XXSTACK
XSTACKX
STACKX0
TACKX0V
ACKX0V3
CKX0V3R
KX0V3RF
X0VERFL
0VERFL0
VERFL0W
ERFL0WX
RFL0WXX
FL0WXXX
L0WXXXX
0WXXXXX
WXXXXXX
XXXXXXX
That would be the output for the string "STACK 0V3RFL0W".
Also the past code:
import sys
import parallel
class Display(object):
def __init__(self):
'''Init and blank the "display".'''
self.display = [' '] * 4
self._update()
def setData(self,data):
'''Bits 0-3 are the "value".
Bits 4-7 are positions 0-3 (first-to-last).
'''
self.display = [' '] * 4
value = data & 0xF
if data & 0x10:
self.display[0] = str(value)
if data & 0x20:
self.display[1] = str(value)
if data & 0x40:
self.display[2] = str(value)
if data & 0x80:
self.display[3] = str(value)
self._update()
def _update(self):
'''Write over the same four terminal positions each time.'''
sys.stdout.write(''.join(self.display) + '\r')
if __name__ == '__main__':
p = Display()
pp=parallel.Parallel()
nums = raw_input("Enter a string of numbers: ")
# Shift over the steam four-at-a-time.
stream = 'XXXX' + nums + 'XXXX'
data = [0] * 4
for i in range(len(stream)-3):
# Precompute data
for pos in range(4):
value = stream[i+pos]
data[pos] = 0 if value == 'X' else (1<<(pos+4)) + int(value)
# "Flicker" the display...
for delay in xrange(1000):
# Display each position briefly.
for d in data:
pp.setData(d)
# Clear the display when done
p.setData(0)
Algorithm outline:
string = "07831505"
while True:
for i in range(7):
# switch display `i` on
notlatch.set(True)
data.set(1 << i)
notlatch.set(False)
time.sleep(<very little>)
notlatch.set(True)
# display character on display `i`
data.set(char_to_7segment(string[i]))
time.sleep(0.01)

PLPGSQL using single quotes in function call (python)

I am having problems when using single quotes in a insert value for a plpgsql function
It looks like this:
"AND (u.firstname LIKE 'koen') OR
(u.firstname LIKE 'dirk')"
This is done with python
I have tried \' and '' and ''' and '''' and ''''' and even '''''''
none of them seem to be working and return the following error:
[FAIL][syntax error at or near "koen"
LINE 1: ...'u.firstname', 'ASC', 'AND (u.firstname LIKE 'koe...
Any help is appreciated!
Thanks a lot!
======================== EDIT =========================
Sorry! here is my plpgsql function:
CREATE FUNCTION get_members(IN in_company_uuid uuid, IN in_start integer, IN in_limit integer, IN in_sort character varying, IN in_order character varying, IN in_querystring CHARACTER VARYING, IN in_filterstring CHARACTER VARYING, IN OUT out_status integer, OUT out_status_description character varying, OUT out_value character varying[]) RETURNS record
LANGUAGE plpgsql
AS $$DECLARE
temp_record RECORD;
temp_out_value VARCHAR[];
--temp_member_struct MEMBER_STRUCT;
temp_iterator INTEGER := 0;
BEGIN
FOR temp_record IN EXECUTE '
SELECT DISTINCT ON
(' || in_sort || ')
u.user_uuid,
u.firstname,
u.preposition,
u.lastname,
array_to_string_ex(ARRAY(SELECT email FROM emails WHERE user_uuid = u.user_uuid)) as emails,
array_to_string_ex(ARRAY(SELECT mobilenumber FROM mobilenumbers WHERE user_uuid = u.user_uuid)) as mobilenumbers,
array_to_string_ex(ARRAY(SELECT c.name FROM targetgroupusers AS tgu LEFT JOIN membercategories as mc ON mc.targetgroup_uuid = tgu.targetgroup_uuid LEFT JOIN categories AS c ON mc.category_uuid = c.category_uuid WHERE tgu.user_uuid = u.user_uuid)) as categories,
array_to_string_ex(ARRAY(SELECT color FROM membercategories WHERE targetgroup_uuid IN(SELECT targetgroup_uuid FROM targetgroupusers WHERE user_uuid = u.user_uuid))) as colors
FROM
membercategories AS mc
LEFT JOIN
targetgroups AS tg
ON
tg.targetgroup_uuid = mc.targetgroup_uuid
LEFT JOIN
targetgroupusers AS tgu
ON
tgu.targetgroup_uuid = tg.targetgroup_uuid
LEFT JOIN
users AS u
ON
u.user_uuid = tgu.user_uuid
WHERE
mc.company_uuid = ''' || in_company_uuid || '''
' || in_querystring || '
' || in_filterstring || '
ORDER BY
' || in_sort || ' ' || in_order || '
OFFSET
' || in_start || '
LIMIT
' || in_limit
LOOP
temp_out_value[temp_iterator] = ARRAY[temp_record.user_uuid::VARCHAR(36),
temp_record.firstname,
temp_record.preposition,
temp_record.lastname,
temp_record.emails,
temp_record.mobilenumbers,
temp_record.categories,
temp_record.colors];
temp_iterator = temp_iterator+1;
END LOOP;
out_status := 0;
out_status_description := 'Members retrieved';
out_value := temp_out_value;
RETURN;
END$$;
Here is how i call the function:
def get_members(companyuuid, start, limit, sort, order, querystring = None, filterstring = None):
logRequest()
def doWork(cursor):
if not companyuuid:
raise Exception("companyuuid cannot be None!")
queryarray = [str(s) for s in querystring.split("|")]
queryfields = ['firstname', 'preposition', 'lastname', 'emails', 'mobilenumbers']
temp_querystring = ""
for j in xrange(len(queryfields)):
for i in xrange(len(queryarray)):
temp_querystring += "(u.%s LIKE ''%%%s%'') OR "%(queryfields[j], queryarray[i])
temp_querystring = "AND %s"%temp_querystring.rstrip(" OR ")
temp_filterstring = filterstring
print "querystring: %s"%temp_querystring
heizoodb.call(cursor=cursor,
scheme="public",
function="get_members",
functionArgs=(companyuuid, start, limit, sort, order, temp_querystring, temp_filterstring),
returnsValue=True)
And my latest error =D
com.gravityzoo.core.libs.sql.PostgreSQLDB.runSQLTransaction: not enough arguments for format string, result=[None]
SQLinjection to be added later ;)
Thanks!
I don't know Python well, but it probably supports data binding where you first prepare a statement (and you don't need quotes around the question marks there):
prepare("..... AND (u.firstname LIKE ?) OR (u.firstname LIKE ?)")
and then you call execute('koen', 'dirk') or whatever that function is called in Python.

Categories

Resources