Reading text file for specfic keyword included inside brackets '{' - python

I would like to read a text file which is like below.
It has Geometry names --> " hvac,OUTLET,INLET,Lamelle,duct and wall"
In this case only 6, but I may vary depending on the different simulation of CFD process.
I would like to extract only the Geometry names and its corresponding 'type'. In my case the geometry and types are " hvac,OUTLET,INLET,Lamelle,duct and wall" and "wall and patch" respectively.
Should I use Parse using XML or just search for the string after '{\n' and '}\n' Keyword .
geometry
{
hvac
{
type wall;
inGroups 1(wall);
nFaces 904403;
startFace 38432281;
}
OUTLET
{
type patch;
nFaces 8228;
startFace 39336684;
}
INLET
{
type patch;
nFaces 347;
startFace 39344912;
}
Lamelle
{
type wall;
inGroups 1(wall);
nFaces 204538;
startFace 39345259;
}
duct
{
type wall;
inGroups 1(wall);
nFaces 535136;
startFace 39549797;
}
wall
{
type wall;
inGroups 1(wall);
nFaces 118659;
startFace 40084933;
}
}

The answer depends on whether you want to support the whole general OpenFOAM's dictionary format, or not.
If you only need to support format similar to what you have shown in the question, then a simple regex like \b(\w+)\s+{\s+type\s+(\w+); would do: https://regex101.com/r/yV8tK2/1 . This can be your option if you fully control how this dictionary is created, though in that case it might be even simpler for you to obtain the needed information directly from the code that creates the dictionary.
However, OpenFOAM's format for dictionaries is much more rich than your example. It can allow for #include directives, can allow for regexs as keys, can allow for referencing of other keys using $ syntax, can allow for comments, C++ code snippets and probably many more (I do not pretend to know it well). A typical example can be two dictionaries:
---- File data.incl:
baseType wall;
---- File data
#inputMode merge;
#include "data.incl"
geometry {
/* foo {
type wrongType; // a commented entry
} */
foo {
type $baseType; // this will expand to wall
...
}
"(bar|buz)" { // this will match bar and buz
...
}
}
If you need to parse any such dictionary, then I strongly recommend you to code in C++ and use standard OpenFOAM classes, which will allow you to do this in just a couple of lines of code.

Related

How to customize the number of characters per line for Python code in Jupyter Notebook?

I've found a solution for automatically (i.e., applied to all notebooks, and without writing additional text in every/any cell) wrapping text in general:
(added to notebook.json in the nbconfig folder)
{
"MarkdownCell": {
"cm_config": {
"lineWrapping": true
}
},
"CodeCell": {
"cm_config": {
"lineWrapping": true
}
}
}
But the standard 80-character wrap cutoff is a bit narrow for visualizing wider dfs.
I've been looking for alternatives to specify a wider character limit for the wrap cutoff.
I tried this proposal (though enlarging the specification beyond 80):
{
"codeCellConfig": {
"lineWrap": "wordWrapColumn",
"wordWrapColumn": 80
}
}
but the wrap disappeared entirely.
Is there a way to enlarge or otherwise customize the character limit for the wrap, and to have it apply automatically to all notebooks?

How to change multiple labels that depends on input and executing code generated to string in C#?

I have no one to ask so I will try here.
Im trying to recreate UI application from python to C# that help our technicians check test log files on multiple servers.
I have lot of labels in UI (using visual studio win forms), that shows technician if the log exist or not on different folders.
for that I need to change specific labels Text property a lot.
Before, in python, I created function that create string of code from different inputs (lists by for loops as program checking servers and folders one by one). And than execute the string variable with "exec" function - simple as that.
for example function that change every label text property to ".........." (something like clear for new search) after clicking on "clear" button
...
for serv1 in range(len(self.servers)):
for i in range(len(self.log_types)):
clearStringCode = ('self.label_' + str(self.servers[serv1]) + '_' + str(self.log_types[i]) + _v.setText("..........")')
exec(clearStringCode)
Im trying to do this same way in my C# program but there is no function as exec in C# language :(
example: I want to change text of label "labelL1TestStart" and few more from list to "NotFound"
private void folderNotFound(string area, string server, List<string> types)
{
foreach (string type in types)
{
string labelName = "label" + server + area + type; //creating button name to string
string toExec = labelName + ".Text = \"Not Found\";"; //creating code to string
SomeFunctionToExecuteTheString(toExec);
}
}
My question is - is there some way how to execute string generated in foreach like this? Or what is the proper way to do this.. changing labels based on input variables? Am I missing something? Im not really programmer. Thank you for answer.
Picture from my python application that Im trying to recreate:
You can try the Find method, something like this
private void folderNotFound(string area, string server, List<string> types)
{
foreach (string type in types)
{
string labelName = "label" + server + area + type; //creating button name to string
var control = this.Controls.Find(labelName, true).FirstOrDefault();
if (control != null)
{
control.Text = "Not Found";
}
else
{
// Do something else here
}
}
}
You can do this by using Control.Controls.Find() to find the control with the specified .Name property and then set its .Text property directly like so:
private void folderNotFound(Control container, string area, string server, List<string> types)
{
foreach (string type in types)
{
string labelName = "label" + server + area + type;
var label = container.Controls.Find(labelName, searchAllChildren: true).FirstOrDefault();
if (label != null)
label.Text = "\"Not found\"";
}
}
The Control container parameter is the form that contains the labels/buttons that you want to adjust the text for. If the folderNotFound() method is defined inside the form that contains the label/button, you can omit that parameter and use this instead:
private void folderNotFound(string area, string server, List<string> types)
{
foreach (string type in types)
{
string labelName = "label" + server + area + type;
var label = this.Controls.Find(labelName, searchAllChildren: true).FirstOrDefault();
if (label != null)
label.Text = "\"Not found\"";
}
}
This all assumes that you have set the Name property of the pertinent labels/buttons in the designer, of course.

GDB command for indexing the members of a structure

I have my structure with several members and I would like to see them all indexed in order.
Struct Ant
{
int type;
char name[100];
long long int food;
}
Now, when I execute the command in gdb
(gdb) ptype struct Ant
$1 = struct
{
int type;
char name[100];
long long int food;
}
I would like to see the output something like
{
0, int type;
1, char name[100];
2, long long int food;
}
Is there a way to get the index of each structure field in order in GDB ?
There is no built-in way to do this. If you need this you can write it yourself in a couple of ways.
One way would be to use the gdb CLI: use set logging and friends to dump the ptype output to a file, then use shell to run some other command on the file to format it the way you like.
Another way would be to use gdb's Python scripting capability to inspect the type and display it how you like. If you search for the pahole command (maybe already on your system, try locate pahole.py -- some Linux distros ship this) you can see an example of how this is done.

Python comments Fail using """ or ''' in dictionary [duplicate]

This question already has an answer here:
Syntax Error on elif statement in Python
(1 answer)
Closed 6 years ago.
I have used Python occasionally for several months, I know we can use # and """ or ''' to comment. But when i wanted to comment some items of a dictionary, with comment words ('''), i failed.
testItems = {
'TestOne':
{
"NameId":101
"Score":99
},
'''
'TestTwo':
{
"NameId":101
"Score":99
}
'''
}
then i get ther error of SyntaxError: invalid syntax pointing to the last ''' position.
I also know there are some indent rule of python language. But i tried so many indent possibility, still fail.
You can only use ''' or """ to comment where strings are allowed as these don't create comments, but just strings.
In the situation you describe, you are not allowed to put a string. Either move the closing } upwards or uncomment your unwanted code part line by line.
Doing
test_items_1 = {
"NameId":101,
"Score":99
}
test_items_2 = {
"NameId":101,
"Score":99
}
testItems = {
'TestOne': test_items_1,
# 'TestTwo': test_items_2,
}
would work as well.
Values in between ''' or """ within dictionary will be considered as another item, not comment.
In your case the the content between ''' is treated as another item's key in that dictionary.
You have to use # to comment the unwanted codes.
Ex:
testItems = {
'TestOne':
{
"NameId":101,
"Score":99
},
# 'TestTwo':
# {
# "NameId":101
# "Score":99
# }
}
As Ilja Everilä mentioned, there is no multi-line comment in python. Although when I copied your code to my pycharm templet, It didn't gave me any error.
Still, in your case, I'd recommend you to use single line commenting method (#). Still, '''...''' or """..."""(convert that part to string) could be used but it will just increase your line of code.
Coming to your question, you are getting an error because:
Your code could be rewritten as :
testItems = {'TestOne': {"NameId":101, "Score":99} ''' 'TestTwo':{
"NameId":101"Score":99 } ''' }
That's how python reads it,
As you want to keep the part in bold, and comment the italics part. You just can't use string. As you can see that python is taking the whole part in braces (Bold + Italics) as single entity. So either use #, or take out that part from there.
You could rewrite as:
testItems = {
'TestOne':
{
"NameId":101,
"Score":99
}
# 'TestTwo':
# {
# "NameId":101,
# "Score":99
# }
}

Parsing an unknown data structure in python

I have a file containing lots of data put in a form similar to this:
Group1 {
Entry1 {
Title1 [{Data1:Member1, Data2:Member2}]
Title2 [{Data3:Member3, Data4:Member4}]
}
Entry2 {
...
}
}
Group2 {
DifferentEntry1 {
DiffTitle1 {
...
}
}
}
Thing is, I don't know how many layers of parentheses there are, and how the data is structured. I need modify the data, and delete entire 'Entry's depending on conditions involving data members before writing everything to a new file. What's the best way of reading in a file like this? Thanks!
The data structure basically seems to be a dict where they keys are strings and the value is either a string or another dict of the same type, so I'd recommend maybe pulling it into that sort of python structure,
eg:
{'group1': {'Entry2': {}, 'Entry1': {'Title1':{'Data4': 'Member4',
'Data1': 'Member1','Data3': 'Member3', 'Data2': 'Member2'},
'Title2': {}}}
At the top level of the file you would create a blank dict, and then for each line you read, you use the identifier as a key, and then when you see a { you create the value for that key as a dict. When you see Key:Value, then instead of creating that key as a dict, you just insert the value normally. When you see a } you have to 'go back up' to the previous dict you were working on and go back to filling that in.
I'd think this whole parser to put the file into a python structure like this could be done in one fairly short recursive function that just called itself to fill in each sub-dict when it saw a { and then returned to its caller upon seeing }
Here is a grammar.
dict_content : NAME ':' NAME [ ',' dict_content ]?
| NAME '{' [ dict_content ]? '}' [ dict_content ]?
| NAME '[' [ list_content ]? ']' [ dict_content ]?
;
list_content : NAME [ ',' list_content ]?
| '{' [ dict_content ]? '}' [ ',' list_content ]?
| '[' [ list_content ]? ']' [ ',' list_content ]?
;
Top level is dict_content.
I'm a little unsure about the comma after dicts and lists embedded in a list, as you didn't provide any example of that.
If you have the grammar for the structure of your data file, or you can create it yourself, you could use a parser generator for Python, like YAPPS: link text.
I have something similar but written in java. It parses a file with the same basic structure with a little different syntax (no '{' and '}' only indentation like in python). It is a very simple script language.
Basically it works like this: It uses a stack to keep track of the inner most block of instructions (or in your case data) and appends every new instruction to the block on the top. If it parses an instruction which expects a new block it is pushed to the stack. If a block ends it pops one element from the stack.
I do not want to post the entire source because it is big and it is available on google code (lizzard-entertainment, revision 405). There is a few things you need to know.
Instruction is an abstract class and it has a block_expected method to indicate wether the concrete instruction needs a block (like loops, etc) In your case this is unnecessary you only need to check for '{'.
Block extends Instruction. It contains a list of instructions and has an add method to add more.
indent_level return how many spaces are preceding the instruction text. This is also unneccessary with '{}' singns.
placeholder
BufferedReader input = null;
try {
input = new BufferedReader(new FileReader(inputFileName));
// Stack of instruction blocks
Stack<Block> stack = new Stack<Block>();
// Push the root block
stack.push(this.topLevelBlock);
String line = null;
Instruction prev = new Noop();
while ((line = input.readLine()) != null) {
// Difference between the indentation of the previous and this line
// You do not need this you will be using {} to specify block boundaries
int level = indent_level(line) - stack.size();
// Parse the line (returns an instruction object)
Instruction inst = Instruction.parse(line.trim().split(" +"));
// If the previous instruction expects a block (for example repeat)
if (prev.block_expected()) {
if (level != 1) {
// TODO handle error
continue;
}
// Push the previous instruction and add the current instruction
stack.push((Block)(prev));
stack.peek().add(inst);
} else {
if (level > 0) {
// TODO handle error
continue;
} else if (level < 0) {
// Pop the stack at the end of blocks
for (int i = 0; i < -level; ++i)
stack.pop();
}
stack.peek().add(inst);
}
prev = inst;
}
} finally {
if (input != null)
input.close();
}
That depends on how the data is structured, and what kind of changes you need to do.
One option might be to parse that into a Python data structure, it seems similar, except that you don't have quotes around the strings. That makes complex manipulation easy.
On the other hand, if all you need to do is make changes that modify some entries to other entries, you can do it with search and replace.
So you need to understand the issue better before you can know what the best way is.
This is a pretty similar problem to XML processing, and there's a lot of Python code to do that. So if you could somehow convert the file to XML, you could just run it through a parser from the standard library. An XML version of your example would be something like this:
<group id="Group1">
<entry id="Entry1">
<title id="Title1"><data id="Data1">Member1</data> <data id="Data2">Member2</data></title>
<title id="Title2"><data id="Data3">Member3</data> <data id="Data4">Member4</data></title>
</entry>
<entry id="Entry2">
...
</entry>
</group>
Of course, converting to XML probably isn't the most straightforward thing to do. But your job is pretty similar to what's already been done with the XML parsers, you just have a different syntax to deal with. So you could take a look at some XML parsing code and write a little Python parser for your data file based on that. (Depending on how the XML parser is implemented, you might even be able to copy the code, just change a few regular expressions, and run it for your file)

Categories

Resources