How to replace a part of variable name in a template file - python

I am trying to write a file from a sample template file.
I need to replace ONLY $UPPERINTERFACE with interface.
This is the sample template.txt
localparam $UPPERINTERFACE_WDTH = 1;
localparam $UPPERINTERFACE_DPTH = 8;
localparam $UPPERINTERFACE_WTCHD = 2;
This is the code:
from string import Template
intf = "interface"
rdfh = open("template.txt", "r").readlines()
wrfh = open("myfile.txt", "w")
for line in rdfh:
s = Template(line)
s = s.substitute(UPPERINTERFACE=intf.upper())
wrfh.write(s)
rdfh.close()
wrfh.close()
Expected output:
localparam interface_WDTH = 1;
localparam interface_DPTH = 8;
localparam interface_WTCHD = 2;
As it is taking $UPPERINTERFACE_WDTH as a variable to be replaced, I am getting following error:
KeyError: 'UPPERINTERFACE_WDTH'
Is there any way I can replace only $UPPERINTERFACE with interface here?

You can use curly braces {} to narrow down the template key as in following template string:
>>> line = 'localparam ${UPPERINTERFACE}_WDTH = 1;'
>>> Template(line).substitute(UPPERINTERFACE=intf.upper())
'localparam INTERFACE_WDTH = 1;'
The documentation states the following:
${identifier} is equivalent to $identifier. It is required when valid identifier characters follow the placeholder but are not part of the placeholder, such as "${noun}ification".

Related

How to read inline-styles from WxPython

I'm trying to put text into a RichTextCtrl and then, after the user has made edits, I want to get the edited text back out along with the styles. Its the second part I'm having trouble with. Out of all the methods to get styles out of the buffer, none of them are really user-friendly.
The best I've come up with is to walk through the text a character at a time with GetStyleForRange(range, style). There has got to be a better way to do this! Here's my code now, which walks through gathering a list of text segments and styles.
Please give me a better way to do this. I have to be missing something.
buffer: wx.richtext.RichTextBuffer = self.rtc.GetBuffer()
end = len(buffer.GetText())
# Variables for text/style reading loop
ch: str
curStyle: str
i: int = 0
style = wx.richtext.RichTextAttr()
text: List[str] = []
textItems: List[Tuple[str, str]] = []
# Read the style of the first character
self.rtc.GetStyleForRange(wx.richtext.RichTextRange(i, i + 1), style)
curStyle = self.describeStyle(style)
# Loop until we hit the end. Use a while loop so we can control the index increment.
while i < end + 1:
# Read the current character and its style as `ch` and `newStyle`
ch = buffer.GetTextForRange(wx.richtext.RichTextRange(i, i))
self.rtc.GetStyleForRange(wx.richtext.RichTextRange(i, i + 1), style)
newStyle = self.describeStyle(style)
# If the style has changed, we flush the collected text and start new collection
if text and newStyle != curStyle and ch != '\n':
newText = "".join(text)
textItems.append((newText, curStyle))
text = []
self.rtc.GetStyleForRange(wx.richtext.RichTextRange(i + 1, i + 2), style)
curStyle = self.describeStyle(style)
# Otherwise, collect the character and continue
else:
i += 1
text.append(ch)
# Capture the last text being collected
newText = "".join(text)
textItems.append((newText, newStyle))
Here's a C++ version of the solution I mentioned in the comment above. It's a simple tree walk using a queue, so I think should be translatable to python easily.
const wxRichTextBuffer& buffer = m_richText1->GetBuffer();
std::deque<const wxRichTextObject*> objects;
objects.push_front(&buffer);
while ( !objects.empty() )
{
const wxRichTextObject* curObject = objects.front();
objects.pop_front();
if ( !curObject->IsComposite() )
{
wxRichTextRange range = curObject->GetRange();
const wxRichTextAttr& attr = curObject->GetAttributes();
// Do something with range and attr here.
}
else
{
// This is a composite object. Add its children to the queue.
// The children are added in reverse order to do a depth first walk.
const wxRichTextCompositeObject* curComposite =
static_cast<const wxRichTextCompositeObject*>(curObject);
size_t childCount = curComposite->GetChildCount() ;
for ( int i = childCount - 1 ; i >= 0 ; --i )
{
objects.push_front(curComposite->GetChild(i));
}
}
}

Knowing how to assign from file

I am trying to know how to assign certain variables from the text files per line in Python.
Text file:
0 Longoria Julia Manager
1 Valdivia Corina Surgeon
In the C++ version, the code to assign each variable per line is coded like this:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int ID[2];
string lName[2];
string fName[2];
string jobTitle[2];
int main()
{
fstream file;
file.open("Employee List.txt");
index = 0;
while (!file.eof())
{
file >> ID[index] >> lName[index] >> fName[index] >> jobTitle[index];
index++;
}
file.close();
return 0;
}
In the Java version, the code to assign each variable per line is coded like this:
import java.io.*;
import java.util.*;
public class fileToVariable
{
public static void main(String[] args)
{
int ID[2] = {0, 0};
String lName[2] = {"", ""};
String fName[2] = {"", ""};
String jobTitle[2] = {"", ""};
try
{
ifstream = new Scanner(new fileInputStream("Employee List.txt"));
}
catch (FileNotFoundException e)
{
}
while (ifstream.hasNextLine())
{
ID[index] = ifstream.nextInt();
lName[index] = ifstream.next();
fName[index] = ifstream.next();
jobTitle[index] = ifstream.next();
index++;
}
}
Does anyone know how the Python equivalent to assigning each variables from the file is coded?
Python doesn't have any built-in methods for reading words directly into variables. Instead, you read the whole line into a string, then use string operations to parse it.
And rather than having separate lists for each attribute, we would normally collect them all into a dictionary, and then make a list of these.
employees = []
line = f.readline()
id, lname, fname, jobtitle = line.split()
employees.append({"id": id, "fname": fname, "lname": lname, "title": jobtitle})
You can use this:
file = open("text.txt", "r")
lines = file.readlines()
ids = []
lnames = []
fnames = []
jobtitles = []
for line in lines:
id1, lname, fname, jobtitle = line.split()
ids.append(id1)
lnames.append(lname)
fnames.append(fname)
jobtitles.append(jobtitle)

parsing of javascript objects using python

friends!
I'm starting to learn python. I have a problem with obtaining the required value from javascript text. Here is the code, which I managed to download from website:
[<script src="//maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAOjFUxXImJbfYejRUbw0-uBSoJppdodHXaiZe2O5Byw3T7kzYihSys_Exmi235-oDCy6xEhVelBMhBQ" type="text/javascript"></script>, <script type="text/javascript">
var map_shop = null;
var marker_shop = null;
function google_maps_shop_initialize()
{
if (GBrowserIsCompatible())
{
map_shop = new GMap2(document.getElementById("map_canvas_shop"));
point_center = new GLatLng(51.6663267, 39.1898874);
marker_shop = new GMarker(point_center);
map_shop.addOverlay(marker_shop);
map_shop.setCenter(point_center, 13);
//Create new Tile Layer
var gTileUrlTemplate = '//mt1.google.com/vt/lyrs=m#121,transit|vm:1&hl=ru&opts=r&x={X}&y={Y}&z={Z}';
var tileLayerOverlay = new GTileLayerOverlay(
new GTileLayer(null, null, null, {
tileUrlTemplate: gTileUrlTemplate,
isPng:true,
opacity:1
})
);
map_shop.addOverlay(tileLayerOverlay);
}
}
google_maps_shop_initialize();
</script>]
I want to print only one line from text, which contains coordinates point_center = new GLatLng(51.6663267, 39.1898874);
I'm trying decide it using re module, but the problem is that number of line may vary and I get empty output with this code:
if re.match("point_center = new GLatLng", line):
print (line)
Desirable output looks like this:
51.6663267, 39.1898874
If the Javascript is .txt format then you can simply do this:
from ast import literal_eval as make_tuple
with open("filename.txt") as f:
for line in f:
if "point_center = new GLatLng" in line:
linestring = line
linestring = linestring[26:]
linestring = make_tuple(linestring)
Your output should be a tuple.

Python convert C header file to dict

I have a C header file which contains a series of classes, and I'm trying to write a function which will take those classes, and convert them to a python dict. A sample of the file is down the bottom.
Format would be something like
class CFGFunctions {
class ABC {
class AA {
file = "abc/aa/functions"
class myFuncName{ recompile = 1; };
};
class BB
{
file = "abc/bb/functions"
class funcName{
recompile=1;
}
}
};
};
I'm hoping to turn it into something like
{CFGFunctions:{ABC:{AA:"myFuncName"}, BB:...}}
# Or
{CFGFunctions:{ABC:{AA:{myFuncName:"string or list or something"}, BB:...}}}
In the end, I'm aiming to get the filepath string (which is actually a path to a folder... but anyway), and the class names in the same class as the file/folder path.
I've had a look on SO, and google and so on, but most things I've found have been about splitting lines into dicts, rather then n-deep 'blocks'
I know I'll have to loop through the file, however, I'm not sure the most efficient way to convert it to the dict.
I'm thinking I'd need to grab the outside class and its relevant brackets, then do the same for the text remaining inside.
If none of that makes sense, it's cause I haven't quite made sense of the process myself haha
If any more info is needed, I'm happy to provide.
The following code is a quick mockup of what I'm sorta thinking...
It is most likely BROKEN and probably does NOT WORK. but its sort of the process that I'm thinking of
def get_data():
fh = open('CFGFunctions.h', 'r')
data = {} # will contain final data model
# would probably refactor some of this into a function to allow better looping
start = "" # starting class name
brackets = 0 # number of brackets
text= "" # temp storage for lines inside block while looping
for line in fh:
# find the class (start
mt = re.match(r'Class ([\w_]+) {', line)
if mt:
if start == "":
start = mt.group(1)
else:
# once we have the first class, find all other open brackets
mt = re.match(r'{', line)
if mt:
# and inc our counter
brackets += 1
mt2 = re.match(r'}', line)
if mt2:
# find the close, and decrement
brackets -= 1
# if we are back to the initial block, break out of the loop
if brackets == 0:
break
text += line
data[start] = {'tempText': text}
====
Sample file
class CfgFunctions {
class ABC {
class Control {
file = "abc\abc_sys_1\Modules\functions";
class assignTracker {
description = "";
recompile = 1;
};
class modulePlaceMarker {
description = "";
recompile = 1;
};
};
class Devices
{
file = "abc\abc_sys_1\devices\functions";
class registerDevice { recompile = 1; };
class getDeviceSettings { recompile = 1; };
class openDevice { recompile = 1; };
};
};
};
EDIT:
If possible, if I have to use a package, I'd like to have it in the programs directory, not the general python libs directory.
As you detected, parsing is necessary to do the conversion. Have a look at the package PyParsing, which is a fairly easy-to-use library to implement parsing in your Python program.
Edit: This is a very symbolic version of what it would take to recognize a very minimalistic grammer - somewhat like the example at the top of the question. It won't work, but it might put you in the right direction:
from pyparsing import ZeroOrMore, OneOrMore, \
Keyword, Literal
test_code = """
class CFGFunctions {
class ABC {
class AA {
file = "abc/aa/functions"
class myFuncName{ recompile = 1; };
};
class BB
{
file = "abc/bb/functions"
class funcName{
recompile=1;
}
}
};
};
"""
class_tkn = Keyword('class')
lbrace_tkn = Literal('{')
rbrace_tkn = Literal('}')
semicolon_tkn = Keyword(';')
assign_tkn = Keyword(';')
class_block = ( class_tkn + identifier + lbrace_tkn + \
OneOrMore(class_block | ZeroOrMore(assignment)) + \
rbrace_tkn + semicolon_tkn \
)
def test_parser(test):
try:
results = class_block.parseString(test)
print test, ' -> ', results
except ParseException, s:
print "Syntax error:", s
def main():
test_parser(test_code)
return 0
if __name__ == '__main__':
main()
Also, this code is only the parser - it does not generate any output. As you can see in the PyParsing docs, you can later add the actions you want. But the first step would be to recognize the what you want to translate.
And a last note: Do not underestimate the complexities of parsing code... Even with a library like PyParsing, which takes care of much of the work, there are many ways to get mired in infinite loops and other amenities of parsing. Implement things step-by-step!
EDIT: A few sources for information on PyParsing are:
http://werc.engr.uaf.edu/~ken/doc/python-pyparsing/HowToUsePyparsing.html
http://pyparsing.wikispaces.com/
(Particularly interesting is http://pyparsing.wikispaces.com/Publications, with a long list of articles - several of them introductory - on PyParsing)
http://pypi.python.org/pypi/pyparsing_helper is a GUI for debugging parsers
There is also a 'tag' Pyparsing here on stackoverflow, Where Paul McGuire (the PyParsing author) seems to be a frequent guest.
* NOTE: *
From PaulMcG in the comments below: Pyparsing is no longer hosted on wikispaces.com. Go to github.com/pyparsing/pyparsing

Searching of strings in a single string in python

In this code, how can I check multiple strings in a single string in single statement?
line = '{ AutoLogin = 0; Captive = 0; Closed = 0; Disabled = 0; LastConnected = "2013-11-27 08:38:10 +0000"; Passpoint = 0; PossiblyHiddenNetwork = 0; SPRoaming = 0; SSID = <534253>; SSIDString = SBS; SecurityType = "WPA/WPA2 Personal"; SystemMode = 1; TemporarilyDisabled = 0; })'
for token in line.split( ';' ):
if 'RecentNetworks' in token:
start = True
if 'LastConnected' in token:
start = True
Try this:
for token in line.split(';'):
start = any(s in token for s in ["RecentNetworks", "LastConnected"])
You can use regular expressions for this:
if re.search(r'RecentNetworks|LastConnected', token):
start = True
I'm not sure if this is faster than the any solution, but I assume it.

Categories