Groovy GStrings and numberformat - groovy

I'm writing a script in groovy to process some files and I have the following method to create the resulting filename
static String formatFileName(String prefix, int counter, String extension) {
String counterS = String.format('%04d', counter)
return "$prefix-$counterS$extension"
}
Is there a more elegant way of formatting the counter in a GString?

Frankly, there's not much you can do here. Making this any shorter is basically nitpicking.
As mentioned in tim_yates' comment, you could make this a one-liner
return "$prefix-${String.format('%04d', counter)}$extension"
I can think of only one way to make it even shorter, which is to give up on GStrings and use sprintf instead, which is another example of Groovy goodness. Namely, an extension method of the Object class. Personally, I find this easier to read than the braces mashup.
return sprintf("%s-%04d%s", prefix, counter, extension)

Related

Can I format variables like strings in python?

I want to use printing command bellow in many places of my script. But I need to keep replacing "Survived" with some other string.
print(df.Survived.value_counts())
Can I automate the process by formating variable the same way as string? So if I want to replace "Survived" with "different" can I use something like:
var = 'different'
text = 'df.{}.value_counts()'.format(var)
print(text)
unfortunately this prints out "df.different.value_counts()" as as a string, while I need to print the value of df.different.value_counts()
I'm pretty sure alot of IDEs, have this option that is called refactoring, and it allows you to change a similar line of code/string on every line of code to what you need it to be.
I'm aware of VSCode's way of refactoring, is by selecting a part of the code and right click to select the option called change all occurances. This will replace the exact code on every line if it exists.
But if you want to do what you proposed, then eval('df.{}.value_counts()'.format(var)) is an option, but this is very unsecured and dangerous, so a more safer approach would be importing the ast module and using it's literal_eval function which is safer. ast.literal_eval('df.{}.value_counts()'.format(var)).
if ast.literal_eval() doesn't work then try this final solution that works.
def cat():
return 1
text = locals()['df.{}.value_counts'.format(var)]()
Found the way: print(df[var].value_counts())

How to get a filename without extension in Kotlin

What is the best way to get the filename from a String or a File object, removing the extension?
I found that creating a File object is a straightforward way to achieve this. No actual file will be created on disk. But take care that only the last extension will be removed:
File("myFile.txt").nameWithoutExtension
File("myFile.tar.gz").nameWithoutExtension
result:
"myFile"
"myFile.tar"
I can not post this as comment, so I have to post this as separate answer.
Your solution will work, but seems like a little bit overkill. Implementation of this function simply calls substringBeforeLast(".") on filename, so I suggest to use this function. By default it will return exact same string, if string has no dot, but you can override this behaviour by providing second parameter.

How to compare strings after calling split in processing?

I am comparing strings from a text file, but for some reason they never match. If I do it in ruby it is very easy, but in processing I can not get it to work.
this is the ruby code that works:
f=File.open("priceMap_current_new.txt")
f.each do |str|
arrstr=str.split(";")
if arrstr.length==1
puts arrstr[0].inspect if arrstr[0]=="next\n"
end
end
Now here's the processing version that doesn't work, actually it doesnt even work without reading from file:
String[] mystr={"number;zero","number;one","number;two","number;three","number;four"};
for(int i=0;i<mystr.length;i++){
String[] numbers=split(mystr[i],";");
if(numbers[0]=="number"){
println("shoooooooooooooooooout");
}
}
Additionally I would like to ask if there's a way to inspect elements like in ruby, its very handy, because if I print pts[0] in processing I get "next" when its actually "next\n"
or also how to check datatypes in processing. Thanks!
Use if (numbers[0].equals("number"))
From: Processing doco
To compare the contents of two Strings, use the equals() method, as in
"if (a.equals(b))", instead of "if (a == b)".

Assigning a mathematical string expression to double variable

I have a mathematical expression in string form like:
string strExpression = "10+100+Math.Sin(90)";
I want to simply assign this expression (at run time) to a float variable (say result), so that it becomes the following code statement:
float result = 10+100+Math.Sin(90);
How can I do this?
You have to compile the expression within a syntactically correct code block. See http://devreminder.wordpress.com/net/net-framework-fundamentals/c-dynamic-math-expression-evaluation/ as an example.
Edit: Or alternatively write your own expression parser if the expression is going to be VERY simple (I wouldn't recommend this though)
You could use CS-Script to dynamically make a class with a method that you can run, if you don't want to write your own parser but rather use C# which you allready know..

How to make this Groovy string search code more efficient?

I'm using the following groovy code to search a file for a string, an account number. The file I'm reading is about 30MB and contains 80,000-120,000 lines. Is there a more efficient way to find a record in a file that contains the given AcctNum? I'm a novice, so I don't know which area to investigate, the toList() or the for-loop. Thanks!
AcctNum = 1234567890
if (testfile.exists())
{
lines = testfile.readLines()
words = lines.toList()
for (word in words)
{
if (word.contains(AcctNum)) { done = true; match = 'YES' ; break }
chunks += 1
if (done) { break }
}
}
Sad to say, I don't even have Groovy installed on my current laptop - but I wouldn't expect you to have to call toList() at all. I'd also hope you could express the condition in a closure, but I'll have to refer to Groovy in Action to check...
Having said that, do you really need it split into lines? Could you just read the whole thing using getText() and then just use a single call to contains()?
EDIT: Okay, if you need to find the actual line containing the record, you do need to call readLines() but I don't think you need to call toList() afterwards. You should be able to just use:
for (line in lines)
{
if (line.contains(AcctNum))
{
// Grab the results you need here
break;
}
}
When you say efficient you usually have to decide which direction you mean: whether it should run quickly, or use as few resources (memory, ...) as possible. Often both lie on opposite sites and you have to pick a trade-off.
If you want to search memory-friendly I'd suggest reading the file line-by-line instead of reading it at once which I suspect it does (I would be wrong there, but in other languages something like readLines reads the whole file into an array of strings).
If you want it to run quickly I'd suggest, as already mentioned, reading in the whole file at once and looking for the given pattern. Instead of just checking with contains you could use indexOf to get the position and then read the record as needed from that position.
I should have explained it better, if I find a record with the AcctNum, I extract out other information on the record...so I thought I needed to split the file into multiple lines.
if you control the format of the file you are reading, the solution is to add in an index.
In fact, this is how databases are able to locate records so quickly.
But for 30MB of data, i think a modern computer with a decent harddrive should do the trick, instead of over complicating the program.

Resources