C
C#15mo ago
Danaew

✅ ConsoleApp method spacing issue

Hey, I've been working on this PromptChoice method to make a new useHorizontal parameter which would essentially place all options on the same row and I've kind of got it working, except for the spacing — I cannot for the life of me figure that part out. Here's a video of what my issue looks like: https://streamable.com/l6ix1s I've attached the code to this post. Also if there are any areas where I can improve the code, please let me know, as I'm still pretty new to C#.
108 Replies
JakenVeina
JakenVeina15mo ago
so, you're doing direct I/O with the console buffer? or you're doing cursor movement magic? and all your menu options are getting overwritten onto the same line? I mean seems pretty straightforward to me you're not properly advancing the cursor position to a new line for each item you're drawing
Danaew
Danaew15mo ago
I'm trying to keep them in the same line, it is pretty simple but I cannot get the spacing correctly for some reason though
JakenVeina
JakenVeina15mo ago
okay, so you're not calculating the column correctly then let's see that logic
Danaew
Danaew15mo ago
It's line 83 Console.Write(isSelected ? $" \x1B[4m{optionText}\x1B[0m" : $" {optionText}");
JakenVeina
JakenVeina15mo ago
I don't have line numbers and the loop for that?
Danaew
Danaew15mo ago
Ok it's in the if statement that I check for useHorizontal
JakenVeina
JakenVeina15mo ago
more importantly, the logic for actually manipulating the cursor
Danaew
Danaew15mo ago
Oh right My bad
JakenVeina
JakenVeina15mo ago
for (int i = 0; i < optionCount; i++)
{
string optionText = options[i];
int lastOptionLength = i == 0 ? 1 : options[i - 1].Length;
bool isSelected = selectedOption == (i + 1);
string padding = isSelected ? "> " : " ";

if (useHorizontal)
Console.SetCursorPosition(startingColumn + (lastOptionLength + 2), startingRow + ((startingRow != 0) ? 3 : 2)) ;
else
Console.SetCursorPosition(startingColumn, startingRow + i + ((startingRow != 0) ? 3 : 2));

Console.ForegroundColor = isSelected ? highlightColor : Console.ForegroundColor;

if (useHorizontal)
Console.Write(isSelected ? $" \x1B[4m{optionText}\x1B[0m" : $" {optionText}");
else
Console.Write(padding + (useDynamicPadding ? optionText.PadRight(maxOptionLength) + " " : optionText));

Console.ResetColor();
}
for (int i = 0; i < optionCount; i++)
{
string optionText = options[i];
int lastOptionLength = i == 0 ? 1 : options[i - 1].Length;
bool isSelected = selectedOption == (i + 1);
string padding = isSelected ? "> " : " ";

if (useHorizontal)
Console.SetCursorPosition(startingColumn + (lastOptionLength + 2), startingRow + ((startingRow != 0) ? 3 : 2)) ;
else
Console.SetCursorPosition(startingColumn, startingRow + i + ((startingRow != 0) ? 3 : 2));

Console.ForegroundColor = isSelected ? highlightColor : Console.ForegroundColor;

if (useHorizontal)
Console.Write(isSelected ? $" \x1B[4m{optionText}\x1B[0m" : $" {optionText}");
else
Console.Write(padding + (useDynamicPadding ? optionText.PadRight(maxOptionLength) + " " : optionText));

Console.ResetColor();
}
this bit?
Danaew
Danaew15mo ago
Yeah Specifically Console.SetCursorPosition(startingColumn + (lastOptionLength + 2), startingRow + ((startingRow != 0) ? 3 : 2)); Copied the wrong thing Idk how to calculate it correctly
JakenVeina
JakenVeina15mo ago
protip: don't make someone have to seek out the relevant code, that's just gonna make them less likely to care enough to help. If you can't identify a small portion of code relevant to the issue, you probably haven't thought through the issue enough for yourself
Danaew
Danaew15mo ago
I got it working with some other code but it still had an issue of them not having the same spacing
JakenVeina
JakenVeina15mo ago
so Console.SetCursorPosition()
Danaew
Danaew15mo ago
Well I didn't expect the method to get that long Was initially like 50 lines Mb tho
JakenVeina
JakenVeina15mo ago
the row part seems fine, so
Danaew
Danaew15mo ago
Yeah it's the column calculation
JakenVeina
JakenVeina15mo ago
what's useHorizontal?
Danaew
Danaew15mo ago
Basically the method has 2 modes One puts the options on separate rows The other puts them on the same row So horizontally
JakenVeina
JakenVeina15mo ago
no, I mean literally when this runs
Danaew
Danaew15mo ago
Uh
JakenVeina
JakenVeina15mo ago
for the output that is wrong what's the value?
Danaew
Danaew15mo ago
Puts options on the same row instead of writeline on each option True
JakenVeina
JakenVeina15mo ago
how do you know?
Danaew
Danaew15mo ago
Cause I set it to true? 😭
JakenVeina
JakenVeina15mo ago
so, you're assuming
Danaew
Danaew15mo ago
It also defaults to true
JakenVeina
JakenVeina15mo ago
no it doesn't
Danaew
Danaew15mo ago
Ok it defaults to false My bad
JakenVeina
JakenVeina15mo ago
if you KNEW everything about how this method was running, there'd be no issue set a breakpoint and prove it
Danaew
Danaew15mo ago
What do you mean by that
JakenVeina
JakenVeina15mo ago
I mean if you think the value of useHorizontal is true set a breakpoint and prove it
Danaew
Danaew15mo ago
I don't get the breakpoint but I call it with useHorizontal true int selectedOption = await PromptChoice(options, highlightColor: ConsoleColor.Blue, useHorizontal: true); otherwise it defaults to false
JakenVeina
JakenVeina15mo ago
you don't know what a breakpoint is?
Danaew
Danaew15mo ago
well I thought u meant something else but if you're being literal then I would know it's true by the layout being different
JakenVeina
JakenVeina15mo ago
that's an assumption
Danaew
Danaew15mo ago
no
JakenVeina
JakenVeina15mo ago
it assumes the layout is working the way you expect/intend set a breakpoint
Danaew
Danaew15mo ago
this is useHorizontal being false
JakenVeina
JakenVeina15mo ago
alternatively you could set a breakpoint
Danaew
Danaew15mo ago
Ok I don't think I understand how to set a breakpoint Would u tell me what I need to do?
JakenVeina
JakenVeina15mo ago
okay what IDE are you using?
Danaew
Danaew15mo ago
Visual Studio 2022
JakenVeina
JakenVeina15mo ago
the easiest way to set a breakpoint is by clicking in the gutter on the left-hand side of a source file there will be a little grey circle that pops up under your mouse
Danaew
Danaew15mo ago
ahh
JakenVeina
JakenVeina15mo ago
click that and it'll turn red, along with the whole line that is a breakpoint
Danaew
Danaew15mo ago
should I do that on the if statement?
JakenVeina
JakenVeina15mo ago
that is where Visual Studio will pause execution of your program, when that line of code is reached do it on any line where you want to inspect what's going on in the code generally, where you want to inspect variable values when the application is paused on a breakpoint (or exception) Visual Studio lets you examine the values of any variables or object fields in scope you can also begin stepping line-by-line through the code, as it executes with the buttons up at the top
Danaew
Danaew15mo ago
ok this is helpful for debugging
JakenVeina
JakenVeina15mo ago
indeed
Danaew
Danaew15mo ago
but I already know the issue lies in how I format the options unless I'm doing something else incorrectly which I don't think I am
Danaew
Danaew15mo ago
this is what I get when I pause on this line
Danaew
Danaew15mo ago
I know useHorizontal is truthy now..
JakenVeina
JakenVeina15mo ago
lol you JavaScript dev, you
Danaew
Danaew15mo ago
no sir I've only been learning some Lua and I recently decided to dabble in C# lol
JakenVeina
JakenVeina15mo ago
really? where are you getting the term "truthy" from?
Danaew
Danaew15mo ago
and or statements from Lua
JakenVeina
JakenVeina15mo ago
does Lua do "truthiness"? it's been a long time, I suppose it probably does for the record, C# doesn't values are true or false and any values that aren't true or false aren't bool and can't be directly related to bool so, at a glance, everything looks fine to me
Danaew
Danaew15mo ago
yeah, it's all fine expect for that one line which is supposed to format the options I really don't know what went wrong, I tried several things
JakenVeina
JakenVeina15mo ago
at this point, you are empowered with the debugger take those calculations and break them apart and start walking through them, step by step you should be able to spot the issue well I can at least say that I get the exact same result
for(var i = 0; i < options.Count; ++i)
{
var lastOptionLength = (i == 0) ? 1 : options[i - 1].Length;
var isSelected = (selectedOptionIndex == i);

Console.SetCursorPosition(startingColumn + (lastOptionLength + 2), startingRow);
if (isSelected)
Console.ForegroundColor = ConsoleColor.White;
Console.Write(isSelected ? $" \x1B[4m{options[i]}\x1B[0m" : $" {options[i]}");
Console.ResetColor();
}
for(var i = 0; i < options.Count; ++i)
{
var lastOptionLength = (i == 0) ? 1 : options[i - 1].Length;
var isSelected = (selectedOptionIndex == i);

Console.SetCursorPosition(startingColumn + (lastOptionLength + 2), startingRow);
if (isSelected)
Console.ForegroundColor = ConsoleColor.White;
Console.Write(isSelected ? $" \x1B[4m{options[i]}\x1B[0m" : $" {options[i]}");
Console.ResetColor();
}
logically, this seems fine to me oh lol nevermind the logic is flawed
Danaew
Danaew15mo ago
ok honestly I've tinkered with it for a few days I even asked ChatGPT I still don't know how to fix it so
JakenVeina
JakenVeina15mo ago
loool yeah if anything, ChatGPT would be likely to make things worse just think it through for yourself how do you figure out what column a particular option should go on?
Danaew
Danaew15mo ago
usually I'd calculate the length of the last option and add a space or 2 for the next option doesn't work here though
JakenVeina
JakenVeina15mo ago
right think that through
Danaew
Danaew15mo ago
I got it to look like this with Console.SetCursorPosition(startingColumn + (maxOptionLength + 4) * i, startingRow + ((startingRow != 0) ? 3 : 2));
JakenVeina
JakenVeina15mo ago
that's wrong
Danaew
Danaew15mo ago
how
JakenVeina
JakenVeina15mo ago
okay look at that formula you just posted how is that different from what your current non-working version does?
Danaew
Danaew15mo ago
well it uses the maxOptionLength which in this case is 9 and adds 4 then multiplies it by the iteration of the loop
JakenVeina
JakenVeina15mo ago
right that's what it does
Danaew
Danaew15mo ago
vs. using lastOptionLength + 2
JakenVeina
JakenVeina15mo ago
right how are those different? logically?
Danaew
Danaew15mo ago
how should I answer that
JakenVeina
JakenVeina15mo ago
maxOptionLength which in this case is 9 and adds 4 then multiplies it by the iteration of the loop
describe this to me, in words what is this doing, functionally why is this the correct calculation
Danaew
Danaew15mo ago
I actually wouldn't know since ChatGPT wrote that
JakenVeina
JakenVeina15mo ago
and there's your problem
Danaew
Danaew15mo ago
it still isn't correct cause there's varying amount of spaces though
JakenVeina
JakenVeina15mo ago
it's not correct for what you're trying to do, sure with dynamic column sizing it IS correct for static column sizing
Danaew
Danaew15mo ago
true I rlly can't figure this out tho I wouldn't have made this post otherwise lol
JakenVeina
JakenVeina15mo ago
if you were going to do this on pencil and paper what do you need to know to write the first column
Danaew
Danaew15mo ago
nothing much I guess just add a space and write the option there's nothing to watch out for since it's the first one
JakenVeina
JakenVeina15mo ago
well, you need to know where to start, right?
Danaew
Danaew15mo ago
uh yea
JakenVeina
JakenVeina15mo ago
that's a piece of info you need to know the option that you want to write that's a piece of info second column what do you need to know?
Danaew
Danaew15mo ago
the way I'm thinking of it, I need the length of the first option and then I should simply setcursorposition 2 spaces forward and write it
JakenVeina
JakenVeina15mo ago
and that works for the second option you need to know where the first option ended which is where it started, plus its length now third column
Danaew
Danaew15mo ago
that should be the same thing
JakenVeina
JakenVeina15mo ago
should it?
Danaew
Danaew15mo ago
oh I see it now
JakenVeina
JakenVeina15mo ago
😉
Danaew
Danaew15mo ago
ok well that's tricky lol
JakenVeina
JakenVeina15mo ago
the ChatGPT version incorporates this by MULTIPLYING the width of each column, by the number it's calculating the length of ALL previous columns, not just one you can do that, or you can just keep a running total
Danaew
Danaew15mo ago
damn ok I need to get the length of the options before the third one
JakenVeina
JakenVeina15mo ago
better option running total
Danaew
Danaew15mo ago
as in?
JakenVeina
JakenVeina15mo ago
var currentColumn = startingColumn;
for(var i = 0; i < options.Count; ++i)
{
var isSelected = (selectedOptionIndex == i);

Console.SetCursorPosition(
left: currentColumn,
top: startingRow);
currentColumn += options[i].Length + 2;

if (isSelected)
Console.ForegroundColor = ConsoleColor.White;
Console.Write(isSelected ? $" \x1B[4m{options[i]}\x1B[0m" : $" {options[i]}");
Console.ResetColor();
}
var currentColumn = startingColumn;
for(var i = 0; i < options.Count; ++i)
{
var isSelected = (selectedOptionIndex == i);

Console.SetCursorPosition(
left: currentColumn,
top: startingRow);
currentColumn += options[i].Length + 2;

if (isSelected)
Console.ForegroundColor = ConsoleColor.White;
Console.Write(isSelected ? $" \x1B[4m{options[i]}\x1B[0m" : $" {options[i]}");
Console.ResetColor();
}
Danaew
Danaew15mo ago
have a variable which is incremented by the option's length each iteration?
JakenVeina
JakenVeina15mo ago
yes more efficient than trying to loop over all the previous options, each time
Danaew
Danaew15mo ago
true
JakenVeina
JakenVeina15mo ago
cause you can't just multiply cause the widths are variable
Danaew
Danaew15mo ago
bro u a genius ngl
JakenVeina
JakenVeina15mo ago
no just experienced
Danaew
Danaew15mo ago
nah u fixed my issue
JakenVeina
JakenVeina15mo ago
doesn't make me a genius plus you fixed your issue I just guided you
Danaew
Danaew15mo ago
held my hand the whole way tbh I appreciate it I guess I should close this now
JakenVeina
JakenVeina15mo ago
that's what I'm here for
Danaew
Danaew15mo ago
yeah, thank you if I have any other issues imma open another post
JakenVeina
JakenVeina15mo ago
please do
Accord
Accord9mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.