Scala - proper way to print a string to file - string

What is the proper way to print a string - and only the string - to file? When I try to do it the standard way known to me, i.e:
def printToFile(o:Object,n:String) = try{
val pathToOutput = "..\\some\\parent\\directory\\"
val path = Paths.get(pathToOutput + n)
val b = new ByteArrayOutputStream()
val os = new ObjectOutputStream(b)
os.writeObject(o)
Files.write(path, b.toByteArray,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING)
}catch{
case _:Exception => println("failed to write")
}
it always seems to prepend
’ NUL ENQtSTXT
Where the part after ENQt seems to vary.
(Doesn't matter if I declare oan Object or a String.)
This is very annoying because I want to print a couple of .dot-Strings (Graphviz) in order to then batch-process the resulting .dot-files to .pdf-files. The prepended nonsense, however, forces me to open each .dot-file and remove it manually - which kind of defeats the purpose of batch-processing them.

This has nothing to do with Scala specifically, it's the way the Java Standard Library works. When you do a writeObject you are writing a Serialized representation of the Object, together with a bunch of additional bytes the JVM can use to re-create that object. If you know the object is a String, then strong-type it (i.e., use printToFile(o:String,n:String) and you can use Files.write(path, o.getBytes, .... Otherwise you could use o.toString.getBytes.

Generally in JVM, if you want to write characters and not bytes, you should prefer *Writer over *OutputStream. In this case (assuming you have a File where you want to write and a String which you want to write):
val writer = new BufferedWriter(new FileWriter(file))
try {
writer.write(string)
} finally {
writer.close()
}
Or with the character-oriented overload of Files.write:
Files.write(path, Collections.singletonList(string), ...)

Related

How to parse a configuration file (kind of a CSV format) using LUA

I am using LUA on a small ESP8266 chip, trying to parse a text string that looks like the one below. I am very new at LUA, and tried many similar scripts found at this forum.
data="
-- String to be parsed\r\n
Tiempo1,20\r\n
Tiempo2a,900\r\n
Hora2b,27\r\n
Tiempo2b,20\r\n
Hora2c,29\r\n
Tiempo2c,18\r\n"
My goal would be to parse the string, and return all the configuration pairs (name/value).
If needed, I can modify the syntax of the config file because it is created by me.
I have been trying something like this:
var1,var2 = data:match("([Tiempo2a,]), ([^,]+)")
But it is returning nil,nil. I think I am on the very wrong way to do this.
Thank you very much for any help.
You need to use gmatch and parse the values excluding non-printable characters (\r\n) at the end of the line or use %d+
local data=[[
-- String to be parsed
Tiempo1,20
Tiempo2a,900
Hora2b,27
Tiempo2b,20
Hora2c,29
Tiempo2c,18]]
local t = {}
for k,v in data:gmatch("(%w-),([^%c]+)") do
t[#t+1] = { k, v }
print(k,v)
end

How to remove comma from string 1,398.90 using groovy

I am not able to remove comma from string 1,398.90 using groovy
def liveprice = '1,398.90';
def liveprice2 = liveprice.replaceAll(',', '')
I would really avoid using regular expressions with numbers
Especially numbers that look like money 💰
You can use DecimalFormat to read that String into a BigDecimal (so you keep precision)
import java.text.*
BigDecimal result = DecimalFormat.instance.with {
parseBigDecimal = true
parse('1,398.90')
}
As mentioned by #daggett, your code works fine. Another alternative way besides regex or replace:
'1,39,9,,,,.90'.split(",").join()
// outputs: 1399.90

pyqt5 fails to inserts bytes

How do you insert a bytes object into a database. Whenever I attempt this I end up with an empty string (not NULL) being inserted.
with open(filepath, 'rb') as f:
filehash = hashlib.md5(f.read()).hexdigest()
img_pkl = pickle.dumps(img, protocol=4)
record = self.tablemodel.record()
record.setValue('originfile_path', filepath)
record.setValue('originfile_hash', filehash)
record.setValue('image', img_pkl)
record.setValue('area', area)
self.tablemodel.insertRecord(-1, record)
The issue was noted on the mailing list but never addressed.
https://www.riverbankcomputing.com/pipermail/pyqt/2016-April/037260.html
It also turns out that it makes more sense to use the table model when you can instead of prepared statements (he also noted a bug in pyqt regarding exec() vs exec_().
You must explicitly convert to a QByteArray.
record.setValue('image', QtCore.QByteArray(img_pkl))
Note: you also have to convert numpy.float64 objects using float()

Converting compressed data in array of bytes to string

Suppose I have an Array[Byte] called cmp. val cmp = Array[Byte](120, -100).
Now, new String(cmp) gives x�, and (new String(cmp)).getBytes gives Array(120, -17, -65, -67) which isn't equal to the original Array[Byte](120, -100). This byte of -100 was part of an Array[Byte] obtained by compressing some string using Zlib.
Note: These operations were done in Scala's repl.
When you've got arbitrary binary data, never ever try to convert it to a string as if it's actually text data which has been encoded into binary data using a normal encoding such as UTF-8. (Even when you do have text data, always specify the encoding when calling the String constructor or getBytes().) Otherwise it's like trying to load an mp3 into an image editor and complaining when it doesn't look like a proper picture...
Basically, you should probably use base64 for this. There are plenty of base64 encoders around; I like this public domain one as it has a pretty sensible interface. Alternatively, you could use hex - that will be more readable if you want to be able to easily understand the original binary content from the text representation manually, but will take more space (2 characters for each original 1 byte, vs base64's 4 characters for each original 3 bytes).
More like Java, but java.io.ByteArrayInputStream, java.util.zip.InflaterInputStream and java.io.DataInputStream can be used.
import java.io._
val bis = new ByteArrayInputStream(cmp)
val zis = new InflaterInputStream(bis)
val dis = new DataInputStream(zis)
val str = dis.readUTF()
To go backwards,
val bos = new ByteArrayOutputStream()
val zos = new InflaterOutputStream(bos)
val dos = new DataOutputStream(zos)
dos.writeUTF(str)
val cmp = bos.toArray

Capture Output to stream and store as a string variable

Although this question relates to 'BioPerl', the question, I believe, is probably more general than that.
Basically I have produced a Bio::Tree::TreeI object and I am trying to convert that into a string variable.
The only way I can come close to converting that to a string variable is to write that tree to a stream using:
# a $tree = Bio::Tree::TreeI->new() (which I know is an actual tree as it prints to the terminal console)
my $treeOut = Bio::TreeIO->new(-format => 'newick')
$treeOut->write_tree($tree)
The output of ->write_tree is "Writes a tree onto the stream" but how do I capture that in a string variable as I can't find another way of returning a string from any of the functions in Bio::TreeIO
You can redirect standard output to variable,
my $captured;
{
local *STDOUT = do { open my $fh, ">", \$captured; $fh };
$treeOut->write_tree($tree);
}
print $captured;
There is an easier way to accomplish the same goal by setting the file handle for BioPerl objects, and I think it is less of a hack. Here is an example:
#!/usr/bin/env perl
use strict;
use warnings;
use Bio::TreeIO;
my $treeio = Bio::TreeIO->new(-format => 'newick', -fh => \*DATA);
my $treeout = Bio::TreeIO->new(-format => 'newick', -fh => \*STDOUT);
while (my $tree = $treeio->next_tree) {
$treeout->write_tree($tree);
}
__DATA__
(A:9.70,(B:8.234,(C:7.932,(D:6.321,((E:2.342,F:2.321):4.231,((((G:4.561,H:3.721):3.9623,
I:3.645):2.341,J:4.893):4.671)):0.234):0.567):0.673):0.456);
Running this script prints the newick string to your terminal, as you would expect. If you use Bio::Phylo (which I recommend), there is a to_string method (IIRC), so you don't have to create an object just to print your trees, you can just do say $tree->to_string.

Resources