Autofill space up to fixed Column width on each line - text

I am trying to set the column width of each line to a fixed "511" width on a large dataset. If the line has less than 511 column width then I want to add space on the end of the line until it has 511 column width. Currently, I am running into a lot of the entries that have irregular column widths. For instance, if the column width is 450 i.e. less than than 511 then I am manually adding space until it has 511 width and if column width exceeds 511 then I am deleting space until it is 511. The current dataset has over 1 million rows so I was wondering if there was faster way to add "spaces" on the end of each line. Would appreciate any help.
Sample of irregular column width

If there aren't many irregular lines (if most lines are 511 characters long), you can use this macro. Otherwise, this macro might take a long time to finish.
COLUMN = 511 + 1; // add 1 to the width
Redraw = false;
nLines = document.GetLines();
for( y = 1; y <= nLines; ++y ) {
document.selection.SetActivePoint( eePosLogical, 1, y );
document.selection.EndOfLine( false, eeLineLogical );
x = document.selection.GetActivePointX( eePosLogical );
if( x < COLUMN ) {
s = "";
for( i = COLUMN - x ; i > 0; --i ) {
s += " ";
}
document.selection.Text = s;
}
else if( x > COLUMN ) {
document.selection.SetActivePoint( eePosLogical, COLUMN, y, true );
document.selection.Delete();
}
}
To run this, save this code as, for instance, AutoSpace.jsee, and then select this file from Select... in the Macros menu. Finally, select Run AutoSpace.jsee in the Macros menu.

Related

Program keeps printing one extra line then what the user inputs

I'm having some trouble trying to build a pyramid out of "#" for mario.c in problem set 1. My program seems to be having some trouble with handling input.
I get these errors:
:( handles a height of 1 correctly
expected ""#"", not "" #"\n"##""
:( handles a height of 2 correctly
expected "" #"\n"##"", not "" #"\n" ##"\n..."
:( handles a height of 8 correctly
expected "" #"\n" ...", not "" #"\n"..."
:( rejects a height of 9, and then accepts a height of 2
expected "" #"\n"##"", not "" #"\n" ##"\n..."
Here is my code:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
height = get_int("How many rows for the pyramid?\n");
}
while (height < 1 || height > 8); //This loops until the user input 1 - 8 rows
for (int row = 0; row <= height; row++) //This says to print a new row until it reaches the user inputted height
{
for (int spaces = (height - (row + 1)); spaces >= 0; spaces--) //This formula prints less spaces as more rows are printed
{
printf(" ");
}
for (int hashes = 1; hashes <= (row + 1); hashes++) //This formula prints more hashes as more rows are printed
{
printf("#");
}
printf("\n");
}
}
Any help is appreciated!!
Your code prints an extra line of hashtags creating a pyramid which is 1 greater in height than the user input. You can see this in the error message you get:
:( handles a height of 1 correctly expected ""#"", not "" #"\n"##""
Hence, the output of your program is #\n## which equates to
#
##
The required output for a height of 1 is:
#
To fix your issue, you have to iterate through your code one lesser time than you do currently for any number. Hence, perhaps consider changing the condition: row <= height; in your for loop.
Consider changing the comparison to just <. By doing this, the code inside the for loop will run one lesser time.

Tabulator - CSV to JSON

I would like to know if there will be a way to transform a csv to the JSON format suitable for the Tabulator library?
The idea would be to have a format as seen on excel :
- the first cell on the top left, empty
- columns A, B, C... AA, AB... according to the number of cells on the longest row
- the line number automatically on the first cell of each line)
I had the idea of doing it directly with loops, but it takes a lot of time I find. I don't see any other way.
Thank you for the help.
Check the following function, I hope this is what you are looking for...
let csvfile = 'title1,title2,title3,title4\n1,2,3,4\n11,22,33,44' //YOUR CSV FILE
let capLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' // ALPHABET SET
let finalJson = [];
let headers;
let line =[];
convertCSV2JSON(csvfile)
function convertCSV2JSON(csv) {
line = csv.split("\n"); //PARSE ALL AVAILABLE LINES INTO ARRAY
result = [];
headers = line[0].split(","); //PARSE ALL AVAILABLE STRING NAMES INTO ARRAY AND KEEP ONLY THE FIRST ONE (HEADER)
line.slice(1).forEach(function(item,i){ //RUN EACH ITEM EXCLUDING COLUMN NAMES
var obj = {};
if(line[i] === null || line[i] === undefined) {
}else{
var entries = line[i+1].split(","); // SEPARATE FOUND ENTRIES EXCLUDING COLUMN NAMES (i+1)
for(var j = 0; j < entries.length; j++) { // PARSE ENTRIES
obj[convert2Letters(j)] = entries[j]; // ASSIGN A LETTER AS COLUMN NAME
}
}
finalJson.push(obj);
})
console.log(finalJson);
}
function convert2Letters(iteration) {
let readyLetter = ''
while (iteration >= 0) {
readyLetter += capLetters[iteration % 26]
iteration = Math.floor(iteration / 26) - 1
}
return readyLetter
}
The fuzzy part was at foreach() function, because you cannot initiate index at your preference... slice() did the trick!
Moreover convert2Letters() function takes an array of letters and on each iteration finds the modulus of 26 letters, removing by one shows you the next combination...
Example:
If you have 30 columns it will give 30 % 26 = 4
4 corresponds to capLetters[4] which is 'E'
calculate next: iteration = Math.floor(iteration / 26) - 1 which means on every 26 increment (0,26,52,78...) it will give (-1,0,1,2...) corresponding. So a 30 columns iteration will have 0 as result which corresponds to capLetters[0] = 'A'
Resulting: 30 columns will give letters 'EA'

CS50 Mario Pyramid in C - Hashes not printing out as expected by code logic

#include <stdio.h>
#include <cs50.h>
int main(void)
{
int height, row, spaces, hashes; //declare all variables to be used
do //prompt the user for valid height inputs that are non-negative and less than 23.
{
printf("Height:");
height = get_int();
} while ((height < 0) || (height > 23));
for (row = 1; row <= height; row ++) // iterate through each row of the height
{
for (spaces = (height - row); spaces >= 0; spaces--) //print the number of spaces for the ith row
{
printf(" ");
}
for (hashes = (row + 1); hashes <= (height + 1); hashes++) //print the number of hashes for each row
{
printf("#");
}
printf("\n");
}
}
Not sure what I am missing in the above code. The spaces print as expected, but the behavior of the hashes is inverted, printing the highest and decreasing.
Let's assume the user submitted 12 as height.
You start the outer loop with row = 1, which gives spaces from height - row = 11 to 0, makes 12 spaces.
The hashes go from row + 1 = 2 to height + 1 = 13, makes 12 hashes.
Next iteration of the loop: 11 spaces, 11 hashes.
What you have expected can be achieved if you changes the second inner loop:
for (hashes = 0; hashes < row; hashes++) //print the number of hashes for each row
If this is not exactly what you need, change beginning of the loop to hashes = 1; or the end to row - 1; or whatever you need.
Your mistake was to assume that hashes++ makes it ascending. It does, technically, but it only changes the order of the loop, not how often it is run. Since you do not need the actual value of hashes, the order is irrelevant. The only thing that counts is how often the loop is run ;)

AutoFit Columns Width using jxl library in java [duplicate]

How to autofit content in cell using jxl api?
I know this is an old question at this point, but I was looking for the solution to this and thought I would post it in case someone else needs it.
CellView Auto-Size
I'm not sure why the FAQ doesn't mention this, because it very clearly exists in the docs.
My code looked like the following:
for(int x=0;x<c;x++)
{
cell=sheet.getColumnView(x);
cell.setAutosize(true);
sheet.setColumnView(x, cell);
}
c stores the number of columns created
cell is just a temporary place holder for the returned CellView object
sheet is my WriteableSheet object
The Api warns that this is a processor intensive function, so it's probably not ideal for large files. But for a small file like mine (<100 rows) it took no noticeable time.
Hope this helps someone.
The method is self explanatory and commented:
private void sheetAutoFitColumns(WritableSheet sheet) {
for (int i = 0; i < sheet.getColumns(); i++) {
Cell[] cells = sheet.getColumn(i);
int longestStrLen = -1;
if (cells.length == 0)
continue;
/* Find the widest cell in the column. */
for (int j = 0; j < cells.length; j++) {
if ( cells[j].getContents().length() > longestStrLen ) {
String str = cells[j].getContents();
if (str == null || str.isEmpty())
continue;
longestStrLen = str.trim().length();
}
}
/* If not found, skip the column. */
if (longestStrLen == -1)
continue;
/* If wider than the max width, crop width */
if (longestStrLen > 255)
longestStrLen = 255;
CellView cv = sheet.getColumnView(i);
cv.setSize(longestStrLen * 256 + 100); /* Every character is 256 units wide, so scale it. */
sheet.setColumnView(i, cv);
}
}
for(int x=0;x<c;x++)
{
cell=sheet.getColumnView(x);
cell.setAutosize(true);
sheet.setColumnView(x, cell);
}
It is fine, instead of scanning all the columns. Pass the column as a parameter.
void display(column)
{
Cell = sheet.getColumnView(column);
cell.setAutosize(true);
sheet.setColumnView(column, cell);
}
So when you wiill be displaying your text you can set the particular length. Can be helpfull for huge excel files.
From the JExcelApi FAQ
How do I do the equivilent of Excel's "Format/Column/Auto Fit Selection"?
There is no API function to do this for you. You'll need to write code that scans the cells in each column, calculates the maximum length, and then calls setColumnView() accordingly. This will get you close to what Excel does but not exactly. Since most fonts have variable width characters, to get the exact same value, you would need to use FontMetrics to calculate the maximum width of each string in the column. No one has posted code on how to do this yet. Feel free to post code to the Yahoo! group or send it directly to the FAQ author's listed at the bottom of this page.
FontMetrics presumably refers to java.awt.FontMetrics. You should be able to work something out with the getLineMetrics(String, Graphics) method I would have though.
CellView's autosize method doesn't work for me all the time. My way of doing this is by programatically set the size(width) of the column based on the highest length of data in the column. Then perform some mathematical operations.
CellView cv = excelSheet.getColumnView(0);
cv.setSize((highest + ((highest/2) + (highest/4))) * 256);
where highest is an int that holds the longest length of data in the column.
setAutosize() method WILL NOT WORK if your cell has over 255 characters. This is related to the Excel 2003 max column width specification: http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP005199291.aspx
You will need to write your own autosize method to handle this case.
Try this exemple:
expandColumns(sheet, 3);
workbook.write();
workbook.close();
private void expandColumn(WritableSheet sheet, int amountOfColumns){
int c = amountOfColumns;
for(int x=0;x<c;x++)
{
CellView cell = sheet.getColumnView(x);
cell.setAutosize(true);
sheet.setColumnView(x, cell);
}
}
Kotlin's implementation
private fun sheetAutoFitColumns(sheet: WritableSheet, columnsIndexesForFit: Array<Int>? = null, startFromRowWithIndex: Int = 0, excludeLastRows : Int = 0) {
for (columnIndex in columnsIndexesForFit?.iterator() ?: IntProgression.fromClosedRange(0, sheet.columns, 1).iterator()) {
val cells = sheet.getColumn(columnIndex)
var longestStrLen = -1
if (cells.isEmpty()) continue
for (j in startFromRowWithIndex until cells.size - excludeLastRows) {
if (cells[j].contents.length > longestStrLen) {
val str = cells[j].contents
if (str == null || str.isEmpty()) continue
longestStrLen = str.trim().length
}
}
if (longestStrLen == -1) continue
val newWidth = if (longestStrLen > 255) 255 else longestStrLen
sheet.setColumnView(columnIndex, newWidth)
}
}
example for use
sheetAutoFitColumns(sheet) // fit all columns by all rows
sheetAutoFitColumns(sheet, arrayOf(0, 3))// fit A and D columns by all rows
sheetAutoFitColumns(sheet, arrayOf(0, 3), 5)// fit A and D columns by rows after 5
sheetAutoFitColumns(sheet, arrayOf(0, 3), 5, 2)// fit A and D columns by rows after 5 and ignore two last rows

How to compare Hough Line positions in OpenCV?

Using VC++ and Open CV. Here's what I'm trying to do:
find the first three nearly-horizontal hough lines and draw them.
find all the nearly-vertical lines and draw them
if any vertical line is above the horizontal line then a FLAG is set to 0
if there is no vertical Hough line above (all are below) the horizontal line then FLAG=1
int n, i,c=0;
int flag = 0;
cvCanny( src, dst, 50, 150, 3 );
lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 10, 5, 5 );
n = lines->total;
for( i = 0; i < n; i++ )
{
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
CvPoint pt1, pt2, hpt1, hpt2, vpt1, vpt2;
int hy = 0, vy = 0;
pt1 = line[0];
pt2 = line[1];
theta = atan( (double)(pt2.y - pt1.y)/(pt2.x - pt1.x) ); /*slope of line*/
degree = theta*180/CV_PI;
if( fabs(degree) < 8) //checking for near horizontal line
{
c++;
if( c > 0 && c <5) /*main horizontal lines come first*/
{
cvLine( out, pt1, pt2, CV_RGB(255, 255,255), 1, CV_AA, 0 );
hpt1 = line[0];
hpt2 = line[1];
if( hpt1.y > hpt2.y ) //finds out lower end-point
hy = hpt1.y;
else
hy = hpt2.y;
}
}
if( fabs(degree) > 70 ) /*near vertical lines*/
{
cvLine( out, pt1, pt2, CV_RGB(255, 255,255), 1, CV_AA, 0 );
vpt1 = line[0];
vpt2 = line[1];
if( vpt1.y > vpt2.y ) //finds upper end-pt of vertical line
vy = vpt1.y;
else
vy = vpt2.y;
if( vy >= hy ) //if vert line is lower than horizontal line
flag = 1;
else
flag = 0;
}
}
display( out, "hough lines" );
return flag;
}
However for an image even if vertical lines are detected above the horizontal line -still the flag is returning 1. So am i counting along the axis wrongly? Please help me out.
The if( fabs(degree) > 70 ) and if( fabs(degree) < 8 ) lines look wrong. An angle of about 180 means almost horizontal ... you probably want to change that, and bear in mind the periodicity of angles (so about 360 is also almost horizontal). A way to nicely handle that would be to use if (fabs(cos(angle - desired_angle)) > 0.996), which means roughly "if angle and desired_angle are within 5 degrees of each other, disregarding direction". 0.996 is roughly the cosine of 5 degrees, if you need it more exact put more digits there - 0.9961946980917455 is a nearer match.
Also, your loop order is off. You don't find the first three nearly-horizontal hough lines and draw them. find all the nearly-vertical lines and draw them if any vertical line is above the horizontal line in this sequence, you loop over all lines, in any order, and process them independently - the vertical ones could come before the horizontal ones, so you wouldn't know what to check for.
Third,
if( hpt1.y > hpt2.y ) //finds out lower end-point
hy = hpt1.y;
else
hy = hpt2.y;
vs
if( vpt1.y > vpt2.y ) //finds upper end-pt of vertical line
vy = vpt1.y;
else
vy = vpt2.y;
You use the same code to find the lower coordinate as to find the higher one. Do you think that could work?
Fourth,
if( vy >= hy ) //if vert line is lower than horizontal line
flag = 1;
else
flag = 0;
The value of flag depends on the LAST pass through this piece of code. This doesn't match the any in your description.
A much easier approche is to not use the PPHL (progressive probabilistic Hough Lines algorithm) but the SHL (standard HL) ! So that you get the polar form of a line with angle and radius ! You can then just check the angle, without calculating it yourself.
If the output angle is around 0° or 180° it's a vertical line, and if it's around 90° it's a horizontal line....

Resources