Remove whitespace padding in matlab fprintf file output - string

I have large matrices of data that look something like this:
DataOut' = [34 1 0.0 -4.75343000000000 0.0291776000000000 5.32835000000000 1.23598000000000 0.890008000000000;
7 1 0.0902364000000000 -4.74065000000000 0.0 1.97133000000000 9.49706000000000 16.1658000000000]
The first two columns are IDs and always integers and the remaining 6 columns are 2 pairs of (X,Y,Z) coordinates (Floats) for each respective ID.
I'm writing the data to a file using the following syntax:
fprintf(' %u %u %-6.12g %-6.12g %-6.12g %-6.12g %-6.12g %-6.12g \r\n', DataOut)
>> 34 1 0 -4.75343 0.0291776 5.32835 1.23598 0.890008
7 1 0.0902364 -4.74065 0 1.97133 9.49706 16.1658
This format is fine in almost all cases except the one highlighted above, where the insignificant trailing zeros are replaced with spaces, leading to a big gap between some columns instead of the single space. The software reading this data really doesn't like all theses spaces and breaks when it finds more than the expected one.
My desired output is to only have a single space between each column:
>> 34 1 0 -4.75343 0.0291776 5.32835 1.23598 0.890008
7 1 0.0902364 -4.74065 0 1.97133 9.49706 16.1658
Does anyone know how to get fprintf do just leave one space after removing the insignificant trailing zeros? Using fprintf is nice because I don't need any loops and when you have several thousand of these matrices to be written out I guess that would be quite slow if I had to do some checking in a loop?

The format spec that you have used for floating point numbers (%-6.12g) species that you want to remove trailing zeros that are non-significant (with a maximum of 12 numbers after the decimal). However, the -6 specifies that you want each field to be at least 6 characters wide. In the case of your 0, it has a width of 1 so fprintf will pad it to be 6 characters wide (hence all the whitespace). If you simply remove the -6 from the beginning of each of your format specifiers you will get the output you desire.
fprintf(' %u %u %.12g %.12g %.12g %.12g %.12g %.12g \r\n', DataOut)
% 34 7 1 1 0 0.0902364 -4.75343 -4.74065
% 2.917760e-02 0 5.32835 1.97133 1.23598 9.49706 0.890008 16.1658

Related

Extract 9 last number from a number of 14 digit

One of my Excel column of my board have to store numbers of 9 digits.
I'm looking for a solution to keep only the 9 last digits of any bigger number past in this specific column. It's only entire number.
Also if after formatting the number it appear that the number starts with 0 the 0 have to be kept. Is there another solution than adding an '0 at first ?
Here is what I already done : (i is the row number / Range01 is Range("A14:O400"))
If Len(Range01.Cells(i,5).value) = 9 Then
Range01.Cells(i,5).Interior.color = vbGreen
ElseIf Len(Range01.Cells(i,5).value) = 8 Then
Range01.Cells(i,5).value = "'0" & Range01.Cells(i,5).value
ElseIf Len(Range01.Cells(i,5).value) > 9 Then
????
Else
Range01.Cells(i,5).Interior.color = vbRed
End If
Thanks for the help.
The simplest way to get the last nine numbers of an integer is:
=MOD(A1,1000000000)
(For your information, that's one billion, a one with nine zeroes.)
If you're interested in showing a number with leading zeroes, you can alter the cell formatting as follows: (the format simply contains nine zeroes)
If you're interested in keeping the zeroes, you might need to use your number as a string, and precede it with a good number of repeated zeroes, something like:
=REPT("0",9-LEN(F8))&F8
Take the length of your number (which gets automatically converted into a string)
Subtract that from 9 (so you know how many zeroes you need)
Create a string, consisting of that number of zeroes
Add your number behind it, using basic concatenation.
You can simply use the math operator of modulus. If you want the last 9 digit you can write:
n % 10000000000
Where n is the number in the column.
In VBA:
MOD(n,1000000000)

Need to add 0 to match the length

I have unique identifiers for each row. For example 19Jan187938 or 19Jan206414 but there are some which are like 19Jan17333. I need to add a 0 before the number if it's 5 digits, so it becomes 19Jan017333.
I tried,
=TEXT(CONCATENATE(19,AB2,C2),"000000")
even with 11 0's, since the total length is 11. Nothing changes.
Try the following:
=CONCATENATE(LEFT(AB2,5),TEXT(RIGHT(AB2,LEN(AB2)-5),"000000"))
It will basically, take the first 5 characters and concatenate that with the remaining characters formatted as a six digit number with leading zeroes
If your identifier is on A1, you can try this:
=IF(LEN(A1)<11;CONCATENATE(LEFT(A1;5);RIGHT("000000"&MID(A1;6;5);6));A1)
See what happens.

Concatenante and include leading zeroes

So currently I am pulling numbers from a spreadsheet that automatically formats their numbers into a certain amount of digits using special number formatting, so that it outputs with leading zeroes.
Example:
(zipcode formatting) 6 digits -
12345 becomes 012345
(Chinese (PRC) formatting) 6 digits -
12 becomes 000012
(Chinese (Taiwan) formatting) 3 digits -
0 becomes 000
My concatenate would put them together with periods between them; however, it does the base numbers instead of the formatting it should be doing.
=CONCATENATE(A1,".",B1,".",C1)
012345 000012 000 becomes 12345.12.0 instead of 012345.000012.000
Is there a function or something that will work to make it pull the converted special number instead of the one typed? It should ALWAYS be 6 digits.6 digits.3 digits.
Try this:
= TEXT(12345,"######000000") & "." & TEXT(12,"######000000") & "." & TEXT(0,"###000")

Plotting datafile with abbreviated values with gnuplot

I have a gnuplot datafile that looks like this:
1 4810 582 573 587
2 99k 67k 56k 40k
3 119k 82k 68k 49k
4 119k 81k 68k 49k
5 120k 81k 65k 45k
6 121k 82k 65k 44k
7 124k 106k 97k 86k
8 128k 134k 131k 131k
9 128k 130k 131k 135k
10 129k 133k 130k 132k
First column will be on the X-axis labeled as "Time", the rest are the different interrupt values with respect to time (i.e. IRQ1, IRQ2, IRQ3, IRQ4)
The problem when generating a plot with this is that gnuplot does not seem to interpret the abbreviated values with the K suffix as numbers in the thousands, but instead as raw values such as 99, 67, 119, etc. Thus the lines will jump from around 5000 at time 1 and drop to around 100 in the graph.
Are there any options to tell gnuplot to automatically interpret abbreviated values and plot them accordingly?
I think there is no direct way of telling gnuplot of how to interpret the input in this case.
You can, however, write your own function that converts the string-input to numbers
check(x)=(pos=strstrt(x,"k"),\
pos > 0 ? real(substr(x,1,pos-1))*1000 : real(x))
The function check first determines the position of the letter 'k' in the input. (The function strstrt returns '0' if the input x does not contain the letter 'k'.)
If the input contains the letter 'k', take the input, discard the last letter, convert the remaining part to a number and multiply it by 1000.
If the input does not contain 'k', return the input
Now you can plot the data file (assuming its name is test):
plot 'test' u 1:(check(stringcolumn(2))) w l
This should do the job!
a non-purely gnuplot, unix solution would use process substitution:
plot "<(sed 's/k/000/g' datafile.dat)" u 1:2 w lp
The sed 's/k/000/g' command replaces all occurrences of the character k with 000 in datafile.dat: e.g. 96k will be replaced with 96000.
The output is similar to the plot posted by #Knorr

Python 3 string formatting with filler more than one character long

I am attempting to format a string in such a way, that I can make a repeating sequence of numbers an arbitrary length.
I've been looking at these examples: How do I format a number with a variable number of digits in Python? and String Formatting in Python 3.
Here's what I tried to do:
print("{0:{1}{2}d}".format(0, 0, 8))
will result in eight pretty 0's all in a row like so: 00000000
but attempting to change the second argument from 0 to 25
print("{0:{1}{2}d}".format(0, 25, 8))
Results in an a single 0 that is as far right as it can go in my console instead of 25252525 So I think the issue is using a string with more than one character as filler instead of a single character.
The specification for string formatting goes like this:
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
In this case, we're only interested in the [0][width] part. [0] is an optional parameter which pads numbers with zeros, so you can format 4 as '004'. [width] specifies the total width of the field.
When you write:
print("{0:{1}{2}d}".format(0, 0, 8))
It becomes:
print("{0:08d}".format(0))
Which is a 0 padded with zeroes up to a length of 8: 00000000.
However, your other example:
print("{0:{1}{2}d}".format(0, 25, 8))
Becomes:
print("{0:258d}".format(0))
Which is a 0 padded with spaces (because there is no 0 in the formatter) up to a length of 258.
I think string formatting is not suited to solve your problem. You can use other fill characters than 0 (using the [fill] option in the formatting spec), but it can't be more than one character.
The simplest way to get what you want is probably this:
>>> print((str(25) * 8)[:8])
25252525

Resources