# Geometric progression

[screenshot] [XML] [Smart Pascal] [JavaScript] [Python] [output]

This demonstration outputs the last term and series (sum) of a geometric progression given the first term, difference and number of terms. It shows how arithmetic can be built up from several blocks in a chain.

We used the Blockly Playground to generate the JavaScript and Python code from the same blocks.

## Theory

In a geometrical progression with first term a and common ratio r, the nth term is arn-1 and the series (sum) of the n terms is a(1 - rn) / (1 - r) provided that r does not equal 1. We use the identifiers floatFirst, floatRatio and intTerms for a, r and n, respectively.

Blockly does not have the direct power function xy, but we can use instead the provided functions ex and ln(x) and the equations ln(xy) = yln(x) and eln(x) = x.

We use our RoundTo function from an earlier demonstration.

The blocks

## XML Code of Blocks

```<xml xmlns="http://www.w3.org/1999/xhtml">
<block type="procedures_defreturn" id="+8*MY2Qgyfr#ChKj%S[#" x="-137" y="-37">
<mutation>
<arg name="floatNum"></arg>
<arg name="intRange"></arg>
</mutation>
<field name="NAME">RoundTo</field>
<comment pinned="false" h="80" w="160">Rounds a number to intRange decimal places</comment>
<statement name="STACK">
<block type="variables_set" id="2![(zYAa3eU8A%RBFEjO">
<field name="VAR">floatPowerOfTen</field>
<value name="VALUE">
<block type="math_single" id="sa.ll@U8][(*UAbd`dLf">
<field name="OP">POW10</field>
<value name="NUM">
<field name="NUM">9</field>
<block type="variables_get" id="(mN=O)n-.:89~)9T_YpD">
<field name="VAR">intRange</field>
</block>
</value>
</block>
</value>
<next>
<block type="variables_set" id="FV_B%twk5HoO90UPD}sC">
<field name="VAR">floatRoundedNum</field>
<value name="VALUE">
<block type="math_arithmetic" id="gT^cKMj-agh:c/t~^Mhf">
<field name="OP">DIVIDE</field>
<value name="A">
<field name="NUM">1</field>
<block type="math_round" id="iHu|9a(oY^+5a|^5w5ZT">
<field name="OP">ROUND</field>
<value name="NUM">
<field name="NUM">3.1</field>
<block type="math_arithmetic" id=",*K_Jyw]]Ed#6t/CkL?%">
<field name="OP">MULTIPLY</field>
<value name="A">
<field name="NUM">1</field>
<block type="variables_get" id="2%gfi[z?WZg\$a0k;52,]">
<field name="VAR">floatNum</field>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="variables_get" id="PI2\$ToO}jebczg/MWneL">
<field name="VAR">floatPowerOfTen</field>
</block>
</value>
</block>
</value>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="variables_get" id="qPBVu8YaeVx#r+XqSQ%g">
<field name="VAR">floatPowerOfTen</field>
</block>
</value>
</block>
</value>
</block>
</next>
</block>
</statement>
<value name="RETURN">
<block type="variables_get" id="W3p@gNtBbOLRNcQQhOCK">
<field name="VAR">floatRoundedNum</field>
</block>
</value>
</block>
<block type="procedures_defnoreturn" id="f6Ob)+^iHN_}K;WTlfaH" x="-137" y="88">
<mutation>
<arg name="floatFirst"></arg>
<arg name="floatRatio"></arg>
<arg name="intTerms"></arg>
</mutation>
<field name="NAME">SeqG</field>
<comment pinned="false" h="80" w="160">Outputs last term and series of geometric progression
with first term floatFirst, difference floatDifference
and number of terms intTerms
</comment>
<statement name="STACK">
<block type="variables_set" id=":wlgM#^Z}DR.rHBszgue">
<field name="VAR">floatLast</field>
<value name="VALUE">
<block type="math_arithmetic" id="ZWP;Z:)=`BIi3Crt7DnQ">
<field name="OP">MULTIPLY</field>
<value name="A">
<field name="NUM">1</field>
<block type="variables_get" id="93w;iJfG%X)ExL=xKZPY">
<field name="VAR">floatFirst</field>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="math_single" id="Bc0d~)gIfk#7+27Yus7(">
<field name="OP">EXP</field>
<value name="NUM">
<field name="NUM">9</field>
<block type="math_arithmetic" id="B`-GJTklWw4D*[U]ia))">
<field name="OP">MULTIPLY</field>
<value name="A">
<field name="NUM">1</field>
<block type="math_arithmetic" id="v]E9:DfZt]x*uqsmI)3P">
<field name="OP">MINUS</field>
<value name="A">
<field name="NUM">1</field>
<block type="variables_get" id="cAzuk~pW?aNAOKGIrr@]">
<field name="VAR">intTerms</field>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
</value>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="math_single" id="UhRTN[T4r(T6P#4X8`+*">
<field name="OP">LN</field>
<value name="NUM">
<field name="NUM">9</field>
<block type="variables_get" id="4Aqb(DR?:c6wYW:JMP_l">
<field name="VAR">floatRatio</field>
</block>
</value>
</block>
</value>
</block>
</value>
</block>
</value>
</block>
</value>
<next>
<block type="variables_set" id="}:#Xq_FxT)|6y*zz1kd{">
<field name="VAR">floatSeries</field>
<value name="VALUE">
<block type="math_arithmetic" id="b5=2GIVXci^43de!)87h">
<field name="OP">MULTIPLY</field>
<value name="A">
<field name="NUM">1</field>
<block type="variables_get" id="(vlnVf6ti_X]7^VV2@\$#">
<field name="VAR">floatFirst</field>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="math_arithmetic" id="[7hEDYksciJ|;sftJdp-">
<field name="OP">DIVIDE</field>
<value name="A">
<field name="NUM">1</field>
<block type="math_arithmetic" id="shY0~ex(`1Z=Z@hiu?e8">
<field name="OP">MINUS</field>
<value name="A">
<field name="NUM">1</field>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="math_single" id="=WZzL%:h8b^ac~Ar4Jn.">
<field name="OP">EXP</field>
<value name="NUM">
<field name="NUM">9</field>
<block type="math_arithmetic" id="|PUwh{uX!4pGC%=N|OtT">
<field name="OP">MULTIPLY</field>
<value name="A">
<field name="NUM">1</field>
<block type="variables_get" id="Urnbq{.2kZ/}1_0lz[_l">
<field name="VAR">intTerms</field>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="math_single" id="eS}-@gsXCu*K5%+CuN0S">
<field name="OP">LN</field>
<value name="NUM">
<field name="NUM">9</field>
<block type="variables_get" id="=Omki`=6r5OV#[.c%eRw">
<field name="VAR">floatRatio</field>
</block>
</value>
</block>
</value>
</block>
</value>
</block>
</value>
</block>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="math_arithmetic" id="LLTJCc!%hm0Y]~v*,(*:">
<field name="OP">MINUS</field>
<value name="A">
<field name="NUM">1</field>
</value>
<value name="B">
<field name="NUM">1</field>
<block type="variables_get" id="D0pv,r2Y!QlugV5JI??^">
<field name="VAR">floatRatio</field>
</block>
</value>
</block>
</value>
</block>
</value>
</block>
</value>
<next>
<block type="text_print" id="76`i3m%!k\$/pUySvo*1#">
<value name="TEXT">
<field name="TEXT">abc</field>
<block type="text_join" id="6hqAv![\$6ILgF_j4U00j">
<mutation items="4"></mutation>
<block type="text" id="exn`,EvF*rERF_hQ,(Eh">
<field name="TEXT">Last term: </field>
</block>
</value>
<block type="procedures_callreturn" id="H4#udWt_)\$@NXH]O^8+?">
<mutation name="RoundTo">
<arg name="floatNum"></arg>
<arg name="intRange"></arg>
</mutation>
<value name="ARG0">
<block type="variables_get" id="um\$BgIKhAj84;4gUQqIE">
<field name="VAR">floatLast</field>
</block>
</value>
<value name="ARG1">
<block type="math_number" id="426Nc*t.|QA4g@5d=Z{R">
<field name="NUM">2</field>
</block>
</value>
</block>
</value>
<block type="text" id="Ih7k1DC{.(i9{*iPOy35">
<field name="TEXT"> Series (sum): </field>
</block>
</value>
<block type="procedures_callreturn" id="@eehCOjyVv)u#Xk8Z/c+">
<mutation name="RoundTo">
<arg name="floatNum"></arg>
<arg name="intRange"></arg>
</mutation>
<value name="ARG0">
<block type="variables_get" id="Vn\$cf[(wRZ;6bZ-L6[P2">
<field name="VAR">floatSeries</field>
</block>
</value>
<value name="ARG1">
<block type="math_number" id=";#taQb|lz{Up,E=JG[cG">
<field name="NUM">2</field>
</block>
</value>
</block>
</value>
</block>
</value>
</block>
</next>
</block>
</next>
</block>
</statement>
</block>
<block type="variables_set" id="#t#Fc,)qcSM4Av@go]TH" x="-137" y="438">
<field name="VAR">floatFirst</field>
<value name="VALUE">
<block type="text_prompt_ext" id="L_\$41vMwhIrk=(Z_mimP">
<mutation type="NUMBER"></mutation>
<field name="TYPE">NUMBER</field>
<value name="TEXT">
</value>
</block>
</value>
<next>
<block type="variables_set" id=".(!d#7ApmSl|!x\$Gr_fp">
<field name="VAR">floatRatio</field>
<value name="VALUE">
<block type="text_prompt_ext" id="?qX1ItfuI?tM#!s=PEEi">
<mutation type="NUMBER"></mutation>
<field name="TYPE">NUMBER</field>
<value name="TEXT">
</value>
</block>
</value>
<next>
<block type="variables_set" id="sap8n;Xv(\$FGvjY^oIvc">
<field name="VAR">intTerms</field>
<value name="VALUE">
<block type="math_round" id="X-2^]y[*vZw!R|bJ#t}]">
<field name="OP">ROUND</field>
<value name="NUM">
<field name="NUM">3.1</field>
<block type="text_prompt_ext" id="nIRgX.M5\$D0,FK4YV)~2">
<mutation type="NUMBER"></mutation>
<field name="TYPE">NUMBER</field>
<value name="TEXT">
<field name="TEXT">Please enter number of terms</field>
</value>
</block>
</value>
</block>
</value>
<next>
<block type="procedures_callnoreturn" id=":IR#oM|!]Uh@Ww+07?5/">
<mutation name="SeqG">
<arg name="floatFirst"></arg>
<arg name="floatRatio"></arg>
<arg name="intTerms"></arg>
</mutation>
<value name="ARG0">
<block type="variables_get" id=":sJVgYxx@F0ubbpOU2z\$">
<field name="VAR">floatFirst</field>
</block>
</value>
<value name="ARG1">
<block type="variables_get" id="dWkYH]Cc:Vy|M%~@6^Rf">
<field name="VAR">floatRatio</field>
</block>
</value>
<value name="ARG2">
<block type="variables_get" id="1)c\$.N?^4izrALE4[av/">
<field name="VAR">intTerms</field>
</block>
</value>
</block>
</next>
</block>
</next>
</block>
</next>
</block>
</xml>

```

## Generated Smart Pascal Code

```var floatFirst: Float;
var floatLast: Float;
var floatNum: Float;
var floatPowerOfTen: Float;
var floatRatio: Float;
var floatRoundedNum: Float;
var floatSeries: Float;
var intRange: Integer;
var intTerms: Integer;

{
Rounds a number to intRange decimal places
}
function RoundTo(floatNum: Float; intRange: Integer): Float;
begin
floatPowerOfTen := Power(10,intRange);
floatRoundedNum := Round(floatNum * floatPowerOfTen) / floatPowerOfTen;
Result := floatRoundedNum;
end;

function Str(v: Variant) : string;
begin
asm
if (@v === 0) {
@Result = '0';
}
else if (@v === '') {
@Result = '';
}
else if (isNaN(@v)) {
@Result = @v;
}
else {
@Result = (@v).toString();
}
end;
end;

{
Outputs last term and series of geometric progression
with first term floatFirst, difference floatDifference
and number of terms intTerms
}
procedure SeqG(floatFirst: Float; floatRatio: Float; intTerms: Integer);
begin
floatLast := floatFirst * Exp((intTerms - 1) * Ln(floatRatio));
floatSeries := floatFirst * ((1 - Exp(intTerms * Ln(floatRatio))) / (1 - floatRatio));
Console.writeln(StrJoin([Str('Last term: '), Str(RoundTo(floatLast, 2)), Str(' Series (sum): '), Str(RoundTo(floatSeries, 2))],''));
end;

floatFirst := StrToFloat(prompt('Please enter first term'));
floatRatio := StrToFloat(prompt('Please enter common ratio'));
intTerms := Round(StrToFloat(prompt('Please enter number of terms')));
SeqG(floatFirst, floatRatio, intTerms);

```

## Generated JavaScript

```var floatRoundedNum, floatPowerOfTen, floatNum, intRange, floatSeries, floatLast, floatRatio, intTerms, floatFirst;

/**
* Rounds a number to intRange decimal places
*/
function RoundTo(floatNum, intRange) {
floatPowerOfTen = Math.pow(10,intRange);
floatRoundedNum = Math.round(floatNum * floatPowerOfTen) / floatPowerOfTen;
return floatRoundedNum;
}

/**
* Outputs last term and series of geometric progression
* with first term floatFirst, difference floatDifference
* and number of terms intTerms
*/
function SeqG(floatFirst, floatRatio, intTerms) {
floatLast = floatFirst * Math.exp((intTerms - 1) * Math.log(floatRatio));
floatSeries = floatFirst * ((1 - Math.exp(intTerms * Math.log(floatRatio))) / (1 - floatRatio));
window.alert(['Last term: ',RoundTo(floatLast, 2),' Series (sum): ',RoundTo(floatSeries, 2)].join(''));
}

floatFirst = parseFloat(window.prompt('Please enter first term'));
floatRatio = parseFloat(window.prompt('Please enter common ratio'));
intTerms = Math.round(parseFloat(window.prompt('Please enter number of terms')));
SeqG(floatFirst, floatRatio, intTerms);

```

## Generated Python Code

```import math

floatRoundedNum = None
floatPowerOfTen = None
floatNum = None
intRange = None
floatSeries = None
floatLast = None
floatRatio = None
intTerms = None
floatFirst = None

"""Rounds a number to intRange decimal places
"""
def RoundTo(floatNum, intRange):
global floatRoundedNum, floatPowerOfTen, floatSeries, floatLast, floatRatio, intTerms, floatFirst
floatPowerOfTen = math.pow(10,intRange)
floatRoundedNum = round(floatNum * floatPowerOfTen) / floatPowerOfTen
return floatRoundedNum

"""Outputs last term and series of geometric progression
with first term floatFirst, difference floatDifference
and number of terms intTerms
"""
def SeqG(floatFirst, floatRatio, intTerms):
global floatRoundedNum, floatPowerOfTen, floatNum, intRange, floatSeries, floatLast
floatLast = floatFirst * math.exp((intTerms - 1) * math.log(floatRatio))
floatSeries = floatFirst * ((1 - math.exp(intTerms * math.log(floatRatio))) / (1 - floatRatio))
print(''.join([str(x) for x in ['Last term: ', RoundTo(floatLast, 2), ' Series (sum): ', RoundTo(floatSeries, 2)]]))

def text_prompt(msg):
try:
return raw_input(msg)
except NameError:
return input(msg)

floatFirst = float(text_prompt('Please enter first term'))
floatRatio = float(text_prompt('Please enter common ratio'))
intTerms = round(float(text_prompt('Please enter number of terms')))
SeqG(floatFirst, floatRatio, intTerms)

```

## Copy of Output

The output on entering the values of 1.6 for the first term, 2.6 for the common ratio and 4 for the number of steps was as follows.

`Last term: 28.12 Series (sum): 44.7`
Programming - a skill for life!

XML, images and generated Smart Pascal code of examples including loops, arrays, validation and recursion