I'm not sure why all programming classes have high math requirements. What they are trying to do is weed out all of the stupid people that can't understand command flow, boolean logic, and the analytical part of programming. You won't really ever do much math beyond simple calculations and random numbers unless the specific program requires it. Plus, derivatives and integration are easier [and faster] to approximate on a computer than to do in real life. Take this for example, its what I wrote for inverse trig functions before scar had them included.
type funct = function (x: extended): extended;
function simpsons_rule(f: funct; a, b: extended): extended;
var
c, h3: extended;
begin
c:= (a + b) / 2.0;
h3:= abs(b - a) / 6.0;
result:= h3 * (f(a) + 4.0 * f(c) + f(b));
end;
function recursive_asr(f: funct; a, b, err, sum: extended): extended;
var
c, left, right: extended;
begin
c:= (a + b) / 2.0;
left:= simpsons_rule(f, a, c);
right:= simpsons_rule(f, c, b);
if (abs(left + right - sum) <= 15 * err) then
begin
result:= left + right + (left + right - sum) / 15;
exit;
end;
result:= recursive_asr(f, a, c, err / 2, left) + recursive_asr(f, c, b, err / 2, right);
end;
function integrate(f: funct; a, b: extended): extended;
begin
result:= recursive_asr(f, a, b, 0.000000000001, simpsons_rule(f, a, b));
end;
function aTan_prime(x: extended): extended;
begin
result:= 1 / (1 + x * x);
end;
function aCos_prime(x: extended): extended;
begin
result:= -1.0 / Sqrt(1.0 - x * x);
end;
function aSin_prime(x: extended): extended;
begin
result:= 1.0 / Sqrt(1.0 - x * x);
end;
function aTan(x: extended): extended;
begin
result:= integrate(@aTan_prime, 0.0, x);
end;
function aCos(x: extended): extended;
begin
if (x = -1.0) then
result:= aTan(1) * 4;
if (abs(x) <> 1) then
result:= integrate(@aCos_prime, 0.0, x) + (aTan(1) * 2);
end;
function aSin(x: extended): extended;
begin
result:= x * (aTan(1) * 2)
if (x <> 1) and (x <> 1.0) then
result:= integrate(@aSin_prime, 0.0, x);
end;