I am trying to emulate a progress loading status in free pascal but i am having difficulty trying to achieve an output that looks like a loading progression status.
The code i have for this is:
percent := 0;
Writeln('Loading');
Repeat
Write('(',percent,'%)');
percent = percent + 1;
Delay(50);
Until percent > 100;
But the output turns out like this:
Loading(0%)(1%)(2%)
When i want it to look like this:
Loading(0%) -> Loading(1%) {The percent variable going up like a loading status}
I only want the percent variable to change in the loop. I've looked over the delete and insert procedures but i don't think it is what i am looking for.
You need to use backspace to go back and write over. Like so:
uses Crt;
var percent: integer;
begin
percent := 0;
Write('Loading ');
Repeat
Write('(',percent:3,'%)'#8#8#8#8#8#8);
percent := percent + 1;
Delay(50);
Until percent > 100;
end.
Related
I have a huge component that can receive a start and end date, plus some floors numbers, and based on these numbers, it generates a table, something like the below image.
Example of this table:
The problem is, how to make this table generate faster?
To generate the floors I use a for a loop.
JavaScript code:
for (let i = 0; i < section.floorQuantity; i++) {
floors.push(i + 1)
}
and for each day, I generate a column with the number of floors as cells (divs).
you can use "useMemo" to cache the same computation and it's result change when input data changes
const computeExpensiveValue=(inputs)=>{
//do something
return result
}
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
I am trying to evaluate the following integral:
where the issue lies with variables like F since it is defined as
F[x_, y_] := f[x, y]/(2*Cto[Norm[x]]*Cto[Norm[y]]) and Cto[x_] := C_t[[Round[x]]]
where C_t is a 1d array and x and y are two vector and I need to access the element of C_t corresponding to the integer of the magnitude of x for example. However, this gives me the following errors when evaluating the integral:
Ci = Flatten[Import["Downloads/ctjulien.txt", "table"]]
Cp = Flatten[Import["Downloads/clphiphi.txt", "table"]]
Subscript[C, t] = Flatten[Import["Downloads/ctobs.txt", "table"]]
Lp[a_] := 1052*{Cos[a], Sin[a]}
vL[L_] := {L, 0}
l[l1_, \[CapitalPhi]1_] :=
l1*{Cos[\[CapitalPhi]1], Sin[\[CapitalPhi]1]}
Cii[x_] := Ci[[Round[x]]]
f[x_, y_] := Cii[Norm[x]]*Dot[x + y, x] + Cii[Norm[y]]*Dot[x + y, y]
Cto[x_] := Subscript[C, t][[Round[x]]]
F[x_, y_] := f[x, y]/(2*Cto[Norm[x]]*Cto[Norm[y]])
Cpp[x_] := Cp[[Round[x]]]
NIntegrate[l1*F[l[l1,\[CapitalPhi]],{L,0}-l[l1,\[CapitalPhi]]]*F[Lp[\[CapitalPhi]p],{L,0}-Lp[\[CapitalPhi]p]]*(Dot[Lp[\[CapitalPhi]p],Lp[\[CapitalPhi]p]-l[l1,\[CapitalPhi]]]*If[Norm[Lp[\[CapitalPhi]p]-l[l1,\[CapitalPhi]]]<=2900,Cpp[Norm[Lp[\[CapitalPhi]p]-l[l1,\[CapitalPhi]]]],0]*f[-{L,0}+l[l1,\[CapitalPhi]],{L,0}-Lp[\[CapitalPhi]p]]+Dot[Lp[\[CapitalPhi]p],Lp[\[CapitalPhi]p]-l[{L,0}-l[l1,\[CapitalPhi]],\[CapitalPhi]]]*If[Norm[Lp[\[CapitalPhi]p]-l[{L,0}-l[l1,\[CapitalPhi]],\[CapitalPhi]]]<=2900,Cpp[Norm[Lp[\[CapitalPhi]p]-l[{L,0}-l[l1,\[CapitalPhi]],\[CapitalPhi]]]],0]*f[-l[l1,\[CapitalPhi]],{L,0}-Lp[\[CapitalPhi]p]]),{\[CapitalPhi],-Pi,Pi},{\[CapitalPhi]p,-Pi,Pi},{l1,2,3000}]
This isn't anywhere near an answer yet, but it is a start. Watch out for Subscript and greek characters and use those appropriately when you test this.
If you insert in front of your code
Ci =Table[RandomInteger[{1,10}],{3000}];
Cp =Table[RandomInteger[{1,10}],{3000}];
Ct =Table[RandomInteger[{1,10}],{3000}];
then you can try to test your code without having your data files present.
If you then test your code you get a stream of "The expression Round[Abs[2+L]] cannot be used as a part" but if you instead insert in front of your code L=2 or some other integer assignment then that error goes away
If you use NIntegrate[yourlongexpression...] then you get a stream of "Round[Sqrt[Abs[l1 Cos[phi]]^2+Abs[l1 Sin[phi]]^2 cannot be used as a part" If you instead use fun[phi_?NumericQ, phip_?NumericQ, l1_?NumericQ]:=yourlongexpression;
NIntegrate[fun[phi,phip,l1]...] then that error goes away.
If you use Table[fun[phi,phip,l1],{phi,-Pi,Pi,Pi/2},{phip,-Pi,Pi,Pi/2},{l1,2,10}] instead of your integral and you look carefully at the output then you should see the word List appearing a number of times. That means you have somelist[[0]] somewhere in your code and Mathematica subscripts all start with 1, not with 0 and that has to be tracked down and fixed.
That is probably the first three or four levels of errors that need to found and fixed.
Inside a foreach loop i have a statement
#(var = var1 + var2 ) ;
the math occurs but the results var gets displayed on the page after each execution. I don't want that to happen just do the math so I can display results at the bottom of the table.
thanks
You need to remove the # symbol as when you're in your for each loop, you're already in a code block.
Your code should look a little like this:
#foreach (var i in a)
{
var x = i + i;
}
I need to go through a HTML string and replace characters with 0 (zero), except tags, spaces and line breaks. I created this code bellow, but it is too slow. Please, can someone help me to make it faster (optimize)?
procedure TForm1.btn1Click(Sender: TObject);
var
Txt: String;
Idx: Integer;
Tag: Boolean;
begin
Tag := False;
Txt := mem1.Text;
For Idx := 0 to Length(Txt) - 1 Do
Begin
If (Txt[Idx] = '<') Then
Tag := True Else
If (Txt[Idx] = '>') Then
Begin
Tag := False;
Continue;
end;
If Tag Then Continue;
If (not (Txt[Idx] in [#10, #13, #32])) Then
Txt[Idx] := '0';
end;
mem2.Text := Txt;
end;
The HTML text will never have "<" or ">" outside tags (in the middle of text), so I do not need to worry about this.
Thank you!
That looks pretty straightforward. It's hard to be sure without profiling the code against the data you're using, (which is always a good idea; if you need to optimize Delphi code, try running it through Sampling Profiler first to get an idea where you're actually spending all your time,) but if I had to make an educated guess, I'd guess that your bottleneck is in this line:
Txt[Idx] := '0';
As part of the compiler's guarantee of safe copy-on-write semantics for the string type, every write to an individual element (character) of a string involves a hidden call to the UniqueString routine. This makes sure that you're not changing a string that something else, somewhere else, holds a reference to.
In this particular case, that's not necessary, because you got the string fresh in the start of this routine and you know it's unique. There's a way around it, if you're careful.
CLEAR AND UNAMBIGUOUS WARNING: Do not do what I'm about to explain without making sure you have a unique string first! The easiest way to accomplish this is to call UniqueString manually. Also, do not do anything during the loop that could assign this string to any other variable. While we're doing this, it's not being treated as a normal string. Failure to heed this warning can cause data corruption.
OK, now that that's been explained, you can use a pointer to access the characters of the string directly, and get around the compiler's safeguards, like so:
procedure TForm1.btn1Click(Sender: TObject);
var
Txt: String;
Idx: Integer;
Tag: Boolean;
current: PChar; //pointer to a character
begin
Tag := False;
Txt := mem1.Text;
UniqueString(txt); //very important
if length(txt) = 0 then
Exit; //If you don't check this, the next line will raise an AV on a blank string
current := #txt[1];
dec(current); //you need to start before element 1, but the compiler won't let you
//assign to element 0
For Idx := 0 to Length(Txt) - 1 Do
Begin
inc(current); //put this at the top of the loop, to handle Continue cases correctly
If (current^ = '<') Then
Tag := True Else
If (current^ = '>') Then
Begin
Tag := False;
Continue;
end;
If Tag Then Continue;
If (not (current^ in [#10, #13, #32])) Then
current^ := '0';
end;
mem2.Text := Txt;
end;
This changes the metaphor. Instead of indexing into the string as an array, we're treating it like a tape, with the pointer as the head, moving forward one character at a time, scanning from beginning to end, and changing the character under it when appropriate. No redundant calls to UniqueString, and no repeatedly calculating offsets, which means this can be a lot faster.
Be very careful when using pointers like this. The compiler's safety checks are there for a good reason, and using pointers steps outside of them. But sometimes, they can really help speed things up in your code. And again, profile before trying anything like this. Make sure that you know what's slowing things down, instead of just thinking you know. If it turns out to be something else that's running slow, don't do this; find a solution to the real problem instead.
Edit: Looks like I was wrong - UniqueString is not the problem. The actual bottleneck seems to be accessing the string by character. Given that my entire answer was irrelevent, I've completely replaced it.
If you use a PChar to avoid recalculating the string offset, while still updating the string via Txt[Idx], the method is much faster (5 seconds down to 0.5 seconds in my test of 1000 runs).
Here's my version:
procedure TForm1.btn1Click(Sender: TObject);
var
Idx: Integer;
Tag: Boolean;
p : PChar;
Txt : string;
begin
Tag := False;
Txt := Mem1.Text;
p := PChar(txt);
Dec(p);
For Idx := 0 to Length(Txt) - 1 Do
Begin
Inc(p);
If (not Tag and (p^ = '<')) Then begin
Tag := True;
Continue;
end
Else If (Tag and (p^ = '>')) Then
Begin
Tag := False;
Continue;
end;
If Tag Then Continue;
If (not (p^ in [#10, #13, #32])) Then begin
Txt[Idx] := '0';
end;
end;
mem2.Text := Txt;
end;
I did some profiling and came up with this solution.
A test for > #32 instead of [#10,#13,#32] gains some speed (thanks #DavidHeffernan).
A better logic in the loop also gives a bit extra speed.
Accessing the string exclusively with the help of a PChar is more effective.
procedure TransformHTML( var Txt : String);
var
IterCnt : Integer;
PTxt : PChar;
tag : Boolean;
begin
PTxt := PChar(Txt);
Dec(PTxt);
tag := false;
for IterCnt := 0 to Length(Txt)-1 do
begin
Inc(PTxt);
if (PTxt^ = '<') then
tag := true
else
if (PTxt^ = '>') then
tag := false
else
if (not tag) and (PTxt^ > #32) then
PTxt^ := '0';
end;
end;
This solution is about 30% more effective than Mason's solution and 2.5 times more effective than Blorgbeard's.
I have this function in Matlab which is supposed to find the smallest value possible for minValuePossible, by varying the two initial set values of inValues. How can I set the fmin search function to NOT try negative values while trying to find the minimum? Also how can I set the number of different variations the fminsearch function performs while trying to find the minimum? Because currently it tries somewhere around 20 different combinations of the two inValues and then completes. Maybe define the amount by which it changes each value? How would I do that?
function Valueminimiser
inValues = [50,50];
minValuePossible = fminsearch(#minimiser, inValues);
function result = minimiser(inValues)
x=inValues(1);
y=inValues(2);
RunMode = 2;
ValueOne = x;
ValueTwo = y;
[maxSCRAout] = main(RunMode,ValueOne,ValueTwo);
result = minValuePossible;
end
end
How can I set the fmin search function to NOT try negative values while trying to find the minimum?
Add the constrains of the values of your minimiser function at its beginning. If you meet this constrains then return a huge function value of minimizer. This will prevent fminsearch consider numbers which are not in your interest:
function result = minimiser(inValues)
if (sum(inValues < 0) > 1) % check if there is any negative number in input variable
result = hugeValue; % give a big value to the result
return; % return to fminsearch - do not execute the rest of the code
end
x=inValues(1);
y=inValues(2);
RunMode = 2;
ValueOne = x;
ValueTwo = y;
[maxSCRAout] = main(RunMode,ValueOne,ValueTwo);
result = minValuePossible;
Also how can I set the number of different variations the fminsearch function performs while trying to find the minimum?
You can define options of fminsearch by using optimset function. The parameter of optimset 'MaxFunEvals' is the maximum number of evaluations -- notice that this cout even the values you constrained, so maybe setting 'TolX' as advised by #slayton might be better if you are concerned about the accuarcy.
options = optimset('MaxFunEvals',numberOfVariations);
minValuePossible = fminsearch(#minimiser, inValues,options);
The docs for fminsearch don't describe a way to restrict the domain of the function you want to minimize.
If you want to restrict the range to all non-negative numbers then you can simply wrap your function in a call to abs, depending on the syntax .
minValuePossible = fminsearch( #(x)(minimiser( abs(x) ) ), inValues);
If you are worried about it constantly converging to the same minima then try a variety of different initial values.
Lastly you can alter the termination tolerances for X and minValuePossible using the TolX and TolFun input parameters. This is done with standard param value syntax: function(...., 'Param', value)
fminsearch( #(x)(minimiser(abs(x))), inValues, 'TolX', x_tolerance);