diff --git a/apps/code/catalog.de.i18n b/apps/code/catalog.de.i18n index 10ad38dae..84088c587 100644 --- a/apps/code/catalog.de.i18n +++ b/apps/code/catalog.de.i18n @@ -20,6 +20,7 @@ PythonAtanh = "Arc hyperbolic tangent" PythonBin = "Convert integer to binary" PythonCeil = "Ceiling" PythonCmathFunction = "Cmath module function prefix" +PythonChoice = "Random choice in array" PythonColor = "Define a rgb color" PythonComplex = "Return a+ib" PythonCopySign = "Return x with the sign of y" @@ -32,6 +33,7 @@ PythonConstantE = "2.718281828459046" PythonErf = "Error function" PythonErfc = "Complementary error function" PythonExp = "Exponential function" +PythonUrandomFunction = "Préfixe fonction module urandom" PythonExpm1 = "Compute exp(x)-1" PythonFabs = "Absolute value" PythonFloor = "Floor" @@ -42,9 +44,11 @@ PythonGetPixel = "Return pixel (x,y) color" PythonHex = "Convert integer to hexadecimal" PythonImportCmath = "Import cmath module" PythonImportKandinsky = "Import kandinsky module" +PythonImportUrandom = "Import urandom module" PythonImportMath = "Import math module" PythonImportFromCmath = "Import cmath module" PythonImportFromKandinsky = "Import kandinsky module" +PythonImportFromUrandom = "Import urandom module" PythonImportFromMath = "Import math module" PythonInt = "Convert x to an integer" PythonIsFinite = "Check if x is finite" @@ -68,10 +72,14 @@ PythonPolar = "z in polar coordinates" PythonPower = "x raised to the power y" PythonPrint = "Print object" PythonRadians = "Convert x from degrees to radians" +PythonRandom = "Random float" +PythonRandint = "Random integer" +PythonRandrange = "Random integer in range" PythonRangeStartStop = "List from start to stop-1" PythonRangeStop = "List from 0 to stop-1" PythonRect = "z in cartesian coordinates" PythonRound = "Round to n digits" +PythonSeed = "Set random seed" PythonSetPixel = "Color pixel (x,y)" PythonSin = "Sine" PythonSinh = "Hyperbolic sine" @@ -81,3 +89,4 @@ PythonSum = "Sum the items of a list" PythonTan = "Tangent" PythonTanh = "Hyperbolic tangent" PythonTrunc = "x truncated to an integer" +PythonUrandomFunction = "Urandom module function prefix" diff --git a/apps/code/catalog.en.i18n b/apps/code/catalog.en.i18n index 10ad38dae..5fa47c851 100644 --- a/apps/code/catalog.en.i18n +++ b/apps/code/catalog.en.i18n @@ -19,6 +19,7 @@ PythonAtan2 = "Return arctan(y/x)" PythonAtanh = "Arc hyperbolic tangent" PythonBin = "Convert integer to binary" PythonCeil = "Ceiling" +PythonChoice = "Random choice in array" PythonCmathFunction = "Cmath module function prefix" PythonColor = "Define a rgb color" PythonComplex = "Return a+ib" @@ -42,9 +43,11 @@ PythonGetPixel = "Return pixel (x,y) color" PythonHex = "Convert integer to hexadecimal" PythonImportCmath = "Import cmath module" PythonImportKandinsky = "Import kandinsky module" +PythonImportUrandom = "Import urandom module" PythonImportMath = "Import math module" PythonImportFromCmath = "Import cmath module" PythonImportFromKandinsky = "Import kandinsky module" +PythonImportFromUrandom = "Import uradom module" PythonImportFromMath = "Import math module" PythonInt = "Convert x to an integer" PythonIsFinite = "Check if x is finite" @@ -68,10 +71,14 @@ PythonPolar = "z in polar coordinates" PythonPower = "x raised to the power y" PythonPrint = "Print object" PythonRadians = "Convert x from degrees to radians" +PythonRandom = "Random float" +PythonRandint = "Random integer" +PythonRandrange = "Random integer in range" PythonRangeStartStop = "List from start to stop-1" PythonRangeStop = "List from 0 to stop-1" PythonRect = "z in cartesian coordinates" PythonRound = "Round to n digits" +PythonSeed = "Set random seed" PythonSetPixel = "Color pixel (x,y)" PythonSin = "Sine" PythonSinh = "Hyperbolic sine" @@ -81,3 +88,4 @@ PythonSum = "Sum the items of a list" PythonTan = "Tangent" PythonTanh = "Hyperbolic tangent" PythonTrunc = "x truncated to an integer" +PythonUrandomFunction = "Urandom module function prefix" \ No newline at end of file diff --git a/apps/code/catalog.es.i18n b/apps/code/catalog.es.i18n index 10ad38dae..28a374b32 100644 --- a/apps/code/catalog.es.i18n +++ b/apps/code/catalog.es.i18n @@ -19,6 +19,7 @@ PythonAtan2 = "Return arctan(y/x)" PythonAtanh = "Arc hyperbolic tangent" PythonBin = "Convert integer to binary" PythonCeil = "Ceiling" +PythonChoice = "Random choice in array" PythonCmathFunction = "Cmath module function prefix" PythonColor = "Define a rgb color" PythonComplex = "Return a+ib" @@ -42,9 +43,11 @@ PythonGetPixel = "Return pixel (x,y) color" PythonHex = "Convert integer to hexadecimal" PythonImportCmath = "Import cmath module" PythonImportKandinsky = "Import kandinsky module" +PythonImportUrandom = "Import urandom module" PythonImportMath = "Import math module" PythonImportFromCmath = "Import cmath module" PythonImportFromKandinsky = "Import kandinsky module" +PythonImportFromUrandom = "Import urandom module" PythonImportFromMath = "Import math module" PythonInt = "Convert x to an integer" PythonIsFinite = "Check if x is finite" @@ -68,10 +71,14 @@ PythonPolar = "z in polar coordinates" PythonPower = "x raised to the power y" PythonPrint = "Print object" PythonRadians = "Convert x from degrees to radians" +PythonRandom = "Random float" +PythonRandint = "Random integer" +PythonRandrange = "Random integer in range" PythonRangeStartStop = "List from start to stop-1" PythonRangeStop = "List from 0 to stop-1" PythonRect = "z in cartesian coordinates" PythonRound = "Round to n digits" +PythonSeed = "Set random seed" PythonSetPixel = "Color pixel (x,y)" PythonSin = "Sine" PythonSinh = "Hyperbolic sine" @@ -81,3 +88,4 @@ PythonSum = "Sum the items of a list" PythonTan = "Tangent" PythonTanh = "Hyperbolic tangent" PythonTrunc = "x truncated to an integer" +PythonUrandomFunction = "Urandom module function prefix" \ No newline at end of file diff --git a/apps/code/catalog.fr.i18n b/apps/code/catalog.fr.i18n index bb2d43644..5c1816d95 100644 --- a/apps/code/catalog.fr.i18n +++ b/apps/code/catalog.fr.i18n @@ -28,6 +28,7 @@ PythonCosh = "Cosinus hyperbolique" PythonDegrees = "Conversion de radians en degrés" PythonDivMod = "Quotient et reste" PythonDrawString = "Affiche un texte au pixel (x,y)" +PythonChoice = "Choix aléatoire dans un tableau" PythonConstantE = "2.718281828459045" PythonErf = "Fonction d'erreur" PythonErfc = "Fonction d'erreur complémentaire" @@ -42,9 +43,11 @@ PythonGetPixel = "Renvoie la couleur du pixel (x,y)" PythonHex = "Conversion entier en hexadécimal" PythonImportCmath = "Importation du module cmath" PythonImportKandinsky = "Importation du module kandinsky" +PythonImportUrandom = "Importation du module urandom" PythonImportMath = "Importation du module math" PythonImportFromCmath = "Importation du module cmath" PythonImportFromKandinsky = "Importation du module kandinsky" +PythonImportFromUrandom = "Importation du module urandom" PythonImportFromMath = "Importation du module math" PythonInt = "Conversion en entier" PythonIsFinite = "Teste si x est fini" @@ -68,10 +71,14 @@ PythonPolar = "Conversion en polaire" PythonPower = "x à la puissance y" PythonPrint = "Affiche l'objet" PythonRadians = "Conversion de degrés en radians" +PythonRandom = "Nombre décimal aléatoire" +PythonRandint = "Entier aléatoire" +PythonRandrange = "Entier aléatoire dans un intervalle" PythonRangeStartStop = "Liste de start à stop-1" PythonRangeStop = "Liste de 0 à stop-1" PythonRect = "Conversion en algébrique" PythonRound = "Arrondi n chiffres" +PythonSeed = "Semence du générateur aléatoire" PythonSetPixel = "Colore le pixel (x,y)" PythonSin = "Sinus" PythonSinh = "Sinus hyperbolique" @@ -81,3 +88,4 @@ PythonSum = "Somme des éléments d'une liste" PythonTan = "Tangente" PythonTanh = "Tangente hyperbolique" PythonTrunc = "Troncature entière" +PythonUrandomFunction = "Préfixe fonction module urandom" \ No newline at end of file diff --git a/apps/code/catalog.pt.i18n b/apps/code/catalog.pt.i18n index ce4f9b340..163b6da77 100644 --- a/apps/code/catalog.pt.i18n +++ b/apps/code/catalog.pt.i18n @@ -19,6 +19,7 @@ PythonAtan2 = "Return arctan(y/x)" PythonAtanh = "Arc hyperbolic tangent" PythonBin = "Convert integer to binary" PythonCeil = "Ceiling" +PythonChoice = "Random choice in array" PythonCmathFunction = "Cmath module function prefix" PythonColor = "Define a rgb color" PythonComplex = "Return a+ib" @@ -42,9 +43,11 @@ PythonGetPixel = "Return pixel (x,y) color" PythonHex = "Convert integer to hexadecimal" PythonImportCmath = "Import cmath module" PythonImportKandinsky = "Import kandinsky module" +PythonImportUrandom = "Import urandom module" PythonImportMath = "Import math module" PythonImportFromCmath = "Import cmath module" PythonImportFromKandinsky = "Import kandinsky module" +PythonImportFromUrandom = "Import urandom module" PythonImportFromMath = "Import math module" PythonInt = "Convert x to an integer" PythonIsFinite = "Check if x is finite" @@ -68,10 +71,14 @@ PythonPolar = "z in polar coordinates" PythonPower = "x raised to the power y" PythonPrint = "Print object" PythonRadians = "Convert x from degrees to radians" +PythonRandom = "Random float" +PythonRandint = "Random integer" +PythonRandrange = "Random integer in range" PythonRangeStartStop = "List from start to stop-1" PythonRangeStop = "List from 0 to stop-1" PythonRect = "z in cartesian coordinates" PythonRound = "Round to n digits" +PythonSeed = "Set random seed" PythonSetPixel = "Color pixel (x,y)" PythonSin = "Sine" PythonSinh = "Hyperbolic sine" @@ -81,3 +88,4 @@ PythonSum = "Sum the items of a list" PythonTan = "Tangent" PythonTanh = "Hyperbolic tangent" PythonTrunc = "x truncated to an integer" +PythonUrandomFunction = "Urandom module function prefix" \ No newline at end of file diff --git a/apps/code/catalog.universal.i18n b/apps/code/catalog.universal.i18n index 819906c7c..8b5166781 100644 --- a/apps/code/catalog.universal.i18n +++ b/apps/code/catalog.universal.i18n @@ -17,6 +17,7 @@ PythonCommandAtan2 = "atan2(y,x)" PythonCommandAtanh = "atanh(x)" PythonCommandBin = "bin(x)" PythonCommandCeil = "ceil(x)" +PythonCommandChoice = "choice([])" PythonCommandCmathFunction = "cmath.function" PythonCommandCmathFunctionWithoutArg = "cmath." PythonCommandColor = "color(r,g,b)" @@ -43,9 +44,11 @@ PythonCommandGetPixel = "get_pixel(x,y)" PythonCommandImportFromCmath = "from cmath import *" PythonCommandImportFromMath = "from math import *" PythonCommandImportFromKandinsky = "from kandinsky import *" +PythonCommandImportFromUrandom = "from urandom import *" PythonCommandHex = "hex(x)" PythonCommandImportCmath = "import cmath" PythonCommandImportKandinsky = "import kandinsky" +PythonCommandImportUrandom = "import urandom" PythonCommandImportMath = "import math" PythonCommandInt = "int(x)" PythonCommandIsFinite = "isfinite(x)" @@ -72,10 +75,14 @@ PythonCommandPolar = "polar(z)" PythonCommandPower = "pow(x,y)" PythonCommandPrint = "print(object)" PythonCommandRadians = "radians(x)" +PythonCommandRandom = "random()" +PythonCommandRandint = "randint(a,b)" +PythonCommandRandrange = "randrange(a,b,c)" PythonCommandRangeStartStop = "range(start, stop)" PythonCommandRangeStop = "range(stop)" PythonCommandRect = "rect(r, arg)" PythonCommandRound = "round(x, n)" +PythonCommandSeed = "seed(x)" PythonCommandSetPixel = "set_pixel(x,y,color)" PythonCommandSin = "sin(x)" PythonCommandSinComplex = "sin(z)" @@ -91,3 +98,5 @@ PythonCommandImag = "z.imag" PythonCommandReal = "z.real" PythonCommandImagWithoutArg = "().imag" PythonCommandRealWithoutArg = "().real" +PythonCommandUrandomFunction = "urandom.function" +PythonCommandUrandomFunctionWithoutArg = "unrandom." diff --git a/apps/code/python_toolbox.cpp b/apps/code/python_toolbox.cpp index 82c68d0bc..c9d7d80ce 100644 --- a/apps/code/python_toolbox.cpp +++ b/apps/code/python_toolbox.cpp @@ -8,17 +8,18 @@ extern "C" { namespace Code { -static constexpr int catalogChildrenCount = 83; +static constexpr int catalogChildrenCount = 91; static constexpr int MathModuleChildrenCount = 43; static constexpr int KandinskyModuleChildrenCount = 7; static constexpr int CMathModuleChildrenCount = 13; +static constexpr int UrandomModuleChildrenCount = 8; static constexpr int conditionsChildrenCount = 9; static constexpr int forLoopChildrenCount = 4; static constexpr int functionsChildrenCount = 2; static constexpr int ifStatementChildrenCount = 5; static constexpr int loopsAndTestsChildrenCount = 4; static constexpr int menuChildrenCount = 4; -static constexpr int modulesChildrenCount = 3; +static constexpr int modulesChildrenCount = 4; static constexpr int whileLoopChildrenCount = 1; @@ -109,6 +110,17 @@ const ToolboxMessageTree KandinskyModuleChildren[KandinskyModuleChildrenCount] = ToolboxMessageTree(I18n::Message::PythonCommandColor, I18n::Message::PythonColor, I18n::Message::PythonCommandColor), ToolboxMessageTree(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString, I18n::Message::PythonCommandDrawString)}; +const ToolboxMessageTree UrandomModuleChildren[UrandomModuleChildrenCount] = { + ToolboxMessageTree(I18n::Message::PythonCommandImportUrandom, I18n::Message::PythonImportUrandom, I18n::Message::PythonCommandImportUrandom), + ToolboxMessageTree(I18n::Message::PythonCommandImportFromUrandom, I18n::Message::PythonImportFromUrandom, I18n::Message::PythonCommandImportFromUrandom), + ToolboxMessageTree(I18n::Message::PythonCommandUrandomFunction, I18n::Message::PythonUrandomFunction, I18n::Message::PythonCommandUrandomFunctionWithoutArg), + ToolboxMessageTree(I18n::Message::PythonCommandRandom, I18n::Message::PythonRandom, I18n::Message::PythonCommandRandom), + ToolboxMessageTree(I18n::Message::PythonCommandRandint, I18n::Message::PythonRandint, I18n::Message::PythonCommandRandint), + ToolboxMessageTree(I18n::Message::PythonCommandRandrange, I18n::Message::PythonRandrange, I18n::Message::PythonCommandRandrange), + ToolboxMessageTree(I18n::Message::PythonCommandSeed, I18n::Message::PythonSeed, I18n::Message::PythonCommandSeed), + ToolboxMessageTree(I18n::Message::PythonCommandChoice, I18n::Message::PythonChoice, I18n::Message::PythonCommandChoice)}; + + const ToolboxMessageTree CMathModuleChildren[CMathModuleChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandImportCmath, I18n::Message::PythonImportCmath, I18n::Message::PythonCommandImportCmath), ToolboxMessageTree(I18n::Message::PythonCommandImportFromCmath, I18n::Message::PythonImportFromCmath, I18n::Message::PythonCommandImportFromCmath), @@ -127,7 +139,8 @@ const ToolboxMessageTree CMathModuleChildren[CMathModuleChildrenCount] = { const ToolboxMessageTree modulesChildren[modulesChildrenCount] = { ToolboxMessageTree(I18n::Message::MathModule, I18n::Message::Default, I18n::Message::Default, MathModuleChildren, MathModuleChildrenCount), ToolboxMessageTree(I18n::Message::CmathModule, I18n::Message::Default, I18n::Message::Default, CMathModuleChildren, CMathModuleChildrenCount), - ToolboxMessageTree(I18n::Message::KandinskyModule, I18n::Message::Default, I18n::Message::Default, KandinskyModuleChildren, KandinskyModuleChildrenCount)}; + ToolboxMessageTree(I18n::Message::KandinskyModule, I18n::Message::Default, I18n::Message::Default, KandinskyModuleChildren, KandinskyModuleChildrenCount), + ToolboxMessageTree(I18n::Message::UrandomModule, I18n::Message::Default, I18n::Message::Default, UrandomModuleChildren, UrandomModuleChildrenCount)}; const ToolboxMessageTree catalogChildren[catalogChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandPound, I18n::Message::PythonPound, I18n::Message::PythonCommandPound), @@ -149,6 +162,7 @@ const ToolboxMessageTree catalogChildren[catalogChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandAtanh, I18n::Message::PythonAtanh, I18n::Message::PythonCommandAtanh), ToolboxMessageTree(I18n::Message::PythonCommandBin, I18n::Message::PythonBin, I18n::Message::PythonCommandBin), ToolboxMessageTree(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil, I18n::Message::PythonCommandCeil), + ToolboxMessageTree(I18n::Message::PythonCommandChoice, I18n::Message::PythonChoice, I18n::Message::PythonCommandChoice), ToolboxMessageTree(I18n::Message::PythonCommandCmathFunction, I18n::Message::PythonCmathFunction, I18n::Message::PythonCommandCmathFunctionWithoutArg), ToolboxMessageTree(I18n::Message::PythonCommandColor, I18n::Message::PythonColor, I18n::Message::PythonCommandColor), ToolboxMessageTree(I18n::Message::PythonCommandComplex, I18n::Message::PythonComplex, I18n::Message::PythonCommandComplex), @@ -170,12 +184,14 @@ const ToolboxMessageTree catalogChildren[catalogChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandImportFromCmath, I18n::Message::PythonImportFromCmath, I18n::Message::PythonCommandImportFromCmath), ToolboxMessageTree(I18n::Message::PythonCommandImportFromKandinsky, I18n::Message::PythonImportFromKandinsky, I18n::Message::PythonCommandImportFromKandinsky), ToolboxMessageTree(I18n::Message::PythonCommandImportFromMath, I18n::Message::PythonImportFromMath, I18n::Message::PythonCommandImportFromMath), + ToolboxMessageTree(I18n::Message::PythonCommandImportFromUrandom, I18n::Message::PythonImportFromUrandom, I18n::Message::PythonCommandImportFromUrandom), ToolboxMessageTree(I18n::Message::PythonCommandGamma, I18n::Message::PythonGamma, I18n::Message::PythonCommandGamma), ToolboxMessageTree(I18n::Message::PythonCommandGetPixel, I18n::Message::PythonGetPixel, I18n::Message::PythonCommandGetPixel), ToolboxMessageTree(I18n::Message::PythonCommandHex, I18n::Message::PythonHex, I18n::Message::PythonCommandHex), ToolboxMessageTree(I18n::Message::PythonCommandImportCmath, I18n::Message::PythonImportCmath, I18n::Message::PythonCommandImportCmath), ToolboxMessageTree(I18n::Message::PythonCommandImportKandinsky, I18n::Message::PythonImportKandinsky, I18n::Message::PythonCommandImportKandinsky), ToolboxMessageTree(I18n::Message::PythonCommandImportMath, I18n::Message::PythonImportMath, I18n::Message::PythonCommandImportMath), + ToolboxMessageTree(I18n::Message::PythonCommandImportUrandom, I18n::Message::PythonImportUrandom, I18n::Message::PythonCommandImportUrandom), ToolboxMessageTree(I18n::Message::PythonCommandInt, I18n::Message::PythonInt, I18n::Message::PythonCommandInt), ToolboxMessageTree(I18n::Message::PythonCommandIsFinite, I18n::Message::PythonIsFinite, I18n::Message::PythonCommandIsFinite), ToolboxMessageTree(I18n::Message::PythonCommandIsInfinite, I18n::Message::PythonIsInfinite, I18n::Message::PythonCommandIsInfinite), @@ -198,11 +214,15 @@ const ToolboxMessageTree catalogChildren[catalogChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandPower, I18n::Message::PythonPower, I18n::Message::PythonCommandPower), ToolboxMessageTree(I18n::Message::PythonCommandPrint, I18n::Message::PythonPrint, I18n::Message::PythonCommandPrint), ToolboxMessageTree(I18n::Message::PythonCommandRadians, I18n::Message::PythonRadians, I18n::Message::PythonCommandRadians), + ToolboxMessageTree(I18n::Message::PythonCommandRandom, I18n::Message::PythonRandom, I18n::Message::PythonCommandRandom), + ToolboxMessageTree(I18n::Message::PythonCommandRandint, I18n::Message::PythonRandint, I18n::Message::PythonCommandRandint), + ToolboxMessageTree(I18n::Message::PythonCommandRandrange, I18n::Message::PythonRandrange, I18n::Message::PythonCommandRandrange), ToolboxMessageTree(I18n::Message::PythonCommandRangeStartStop, I18n::Message::PythonRangeStartStop, I18n::Message::PythonCommandRangeStartStop), ToolboxMessageTree(I18n::Message::PythonCommandRangeStop, I18n::Message::PythonRangeStop, I18n::Message::PythonCommandRangeStop), ToolboxMessageTree(I18n::Message::PythonCommandRect, I18n::Message::PythonRect, I18n::Message::PythonCommandRect), ToolboxMessageTree(I18n::Message::PythonCommandRound, I18n::Message::PythonRound, I18n::Message::PythonCommandRound), ToolboxMessageTree(I18n::Message::PythonCommandSetPixel, I18n::Message::PythonSetPixel, I18n::Message::PythonCommandSetPixel), + ToolboxMessageTree(I18n::Message::PythonCommandSeed, I18n::Message::PythonSeed, I18n::Message::PythonCommandSeed), ToolboxMessageTree(I18n::Message::PythonCommandSin, I18n::Message::PythonSin, I18n::Message::PythonCommandSin), ToolboxMessageTree(I18n::Message::PythonCommandSinh, I18n::Message::PythonSinh, I18n::Message::PythonCommandSinh), ToolboxMessageTree(I18n::Message::PythonCommandSorted, I18n::Message::PythonSorted, I18n::Message::PythonCommandSorted), @@ -212,7 +232,8 @@ const ToolboxMessageTree catalogChildren[catalogChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandTanh, I18n::Message::PythonTanh, I18n::Message::PythonCommandTanh), ToolboxMessageTree(I18n::Message::PythonCommandTrunc, I18n::Message::PythonTrunc, I18n::Message::PythonCommandTrunc), ToolboxMessageTree(I18n::Message::PythonCommandImag, I18n::Message::PythonImag, I18n::Message::PythonCommandImagWithoutArg), - ToolboxMessageTree(I18n::Message::PythonCommandReal, I18n::Message::PythonReal, I18n::Message::PythonCommandRealWithoutArg)}; + ToolboxMessageTree(I18n::Message::PythonCommandReal, I18n::Message::PythonReal, I18n::Message::PythonCommandRealWithoutArg), + ToolboxMessageTree(I18n::Message::PythonCommandUrandomFunction, I18n::Message::PythonUrandomFunction, I18n::Message::PythonCommandUrandomFunctionWithoutArg),}; const ToolboxMessageTree functionsChildren[functionsChildrenCount] = { ToolboxMessageTree(I18n::Message::PythonCommandDefWithArg, I18n::Message::Default, I18n::Message::PythonCommandDef), diff --git a/apps/code/toolbox.universal.i18n b/apps/code/toolbox.universal.i18n index d8aa0e6ef..168a76000 100644 --- a/apps/code/toolbox.universal.i18n +++ b/apps/code/toolbox.universal.i18n @@ -43,3 +43,4 @@ ForInRange1ArgLoopWithArg = "for i in range(size):\n instruction" PythonCommandDef = "def ():\n " PythonCommandDefWithArg = "def function(x):" PythonCommandReturn = "return " +UrandomModule = "urandom" diff --git a/python/Makefile b/python/Makefile index e22e7d26f..d746b32fb 100644 --- a/python/Makefile +++ b/python/Makefile @@ -138,6 +138,11 @@ py_objs = $(addprefix python/src/py/,\ py_objs += python/src/py/emitnative.o python/src/py/emitnative.o: CFLAGS += -DN_THUMB + +extmod_objs += $(addprefix python/src/extmod/,\ + modurandom.o \ +) + #extmod_objs += $(addprefix python/src/extmod/,\ moductypes.o \ modujson.o \ @@ -205,4 +210,4 @@ $(py_objs) $(extmod_objs) $(port_objs): python/port/genhdr/qstrdefs.generated.h # List all objects needed -objs += $(py_objs) $(port_objs) +objs += $(extmod_objs) $(py_objs) $(port_objs) diff --git a/python/port/genhdr/qstrdefs.in.h b/python/port/genhdr/qstrdefs.in.h index 5815e5d44..23e34b5ff 100644 --- a/python/port/genhdr/qstrdefs.in.h +++ b/python/port/genhdr/qstrdefs.in.h @@ -275,3 +275,12 @@ Q(value) Q(values) Q(zip) Q({:#b}) +Q(urandom) +Q(getrandbits) +Q(seed) +Q(random) +Q(randint) +Q(randrange) +Q(randfloat) +Q(choice) +Q(uniform) diff --git a/python/src/extmod/modurandom.c b/python/src/extmod/modurandom.c new file mode 100644 index 000000000..4b63dace4 --- /dev/null +++ b/python/src/extmod/modurandom.c @@ -0,0 +1,226 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +//#include "py/nlr.h" +#include "py/runtime.h" + +#if MICROPY_PY_URANDOM + +// Yasmarang random number generator +// by Ilya Levin +// http://www.literatecode.com/yasmarang +// Public Domain + +STATIC uint32_t yasmarang_pad = 0xeda4baba, yasmarang_n = 69, yasmarang_d = 233; +STATIC uint8_t yasmarang_dat = 0; + +STATIC uint32_t yasmarang(void) +{ + yasmarang_pad += yasmarang_dat + yasmarang_d * yasmarang_n; + yasmarang_pad = (yasmarang_pad<<3) + (yasmarang_pad>>29); + yasmarang_n = yasmarang_pad | 2; + yasmarang_d ^= (yasmarang_pad<<31) + (yasmarang_pad>>1); + yasmarang_dat ^= (char) yasmarang_pad ^ (yasmarang_d>>8) ^ 1; + + return (yasmarang_pad^(yasmarang_d<<5)^(yasmarang_pad>>18)^(yasmarang_dat<<1)); +} /* yasmarang */ + +// End of Yasmarang + +#if MICROPY_PY_URANDOM_EXTRA_FUNCS + +// returns an unsigned integer below the given argument +// n must not be zero +STATIC uint32_t yasmarang_randbelow(uint32_t n) { + uint32_t mask = 1; + while ((n & mask) < n) { + mask = (mask << 1) | 1; + } + uint32_t r; + do { + r = yasmarang() & mask; + } while (r >= n); + return r; +} + +#endif + +STATIC mp_obj_t mod_urandom_getrandbits(mp_obj_t num_in) { + int n = mp_obj_get_int(num_in); + if (n > 32 || n == 0) { + mp_raise_ValueError(NULL); + } + uint32_t mask = ~0; + // Beware of C undefined behavior when shifting by >= than bit size + mask >>= (32 - n); + return mp_obj_new_int_from_uint(yasmarang() & mask); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_getrandbits_obj, mod_urandom_getrandbits); + +STATIC mp_obj_t mod_urandom_seed(mp_obj_t seed_in) { + mp_uint_t seed = mp_obj_get_int_truncated(seed_in); + yasmarang_pad = seed; + yasmarang_n = 69; + yasmarang_d = 233; + yasmarang_dat = 0; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_seed_obj, mod_urandom_seed); + +#if MICROPY_PY_URANDOM_EXTRA_FUNCS + +STATIC mp_obj_t mod_urandom_randrange(size_t n_args, const mp_obj_t *args) { + mp_int_t start = mp_obj_get_int(args[0]); + if (n_args == 1) { + // range(stop) + if (start > 0) { + return mp_obj_new_int(yasmarang_randbelow(start)); + } else { + goto error; + } + } else { + mp_int_t stop = mp_obj_get_int(args[1]); + if (n_args == 2) { + // range(start, stop) + if (start < stop) { + return mp_obj_new_int(start + yasmarang_randbelow(stop - start)); + } else { + goto error; + } + } else { + // range(start, stop, step) + mp_int_t step = mp_obj_get_int(args[2]); + mp_int_t n; + if (step > 0) { + n = (stop - start + step - 1) / step; + } else if (step < 0) { + n = (stop - start + step + 1) / step; + } else { + goto error; + } + if (n > 0) { + return mp_obj_new_int(start + step * yasmarang_randbelow(n)); + } else { + goto error; + } + } + } + +error: + mp_raise_ValueError(NULL); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_urandom_randrange_obj, 1, 3, mod_urandom_randrange); + +STATIC mp_obj_t mod_urandom_randint(mp_obj_t a_in, mp_obj_t b_in) { + mp_int_t a = mp_obj_get_int(a_in); + mp_int_t b = mp_obj_get_int(b_in); + if (a <= b) { + return mp_obj_new_int(a + yasmarang_randbelow(b - a + 1)); + } else { + mp_raise_ValueError(NULL); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_randint_obj, mod_urandom_randint); + +STATIC mp_obj_t mod_urandom_choice(mp_obj_t seq) { + mp_int_t len = mp_obj_get_int(mp_obj_len(seq)); + if (len > 0) { + return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL); + } else { + nlr_raise(mp_obj_new_exception(&mp_type_IndexError)); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_choice_obj, mod_urandom_choice); + +#if MICROPY_PY_BUILTINS_FLOAT + +// returns a number in the range [0..1) using Yasmarang to fill in the fraction bits +STATIC mp_float_t yasmarang_float(void) { + #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE + typedef uint64_t mp_float_int_t; + #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT + typedef uint32_t mp_float_int_t; + #endif + union { + mp_float_t f; + #if MP_ENDIANNESS_LITTLE + struct { mp_float_int_t frc:MP_FLOAT_FRAC_BITS, exp:MP_FLOAT_EXP_BITS, sgn:1; } p; + #else + struct { mp_float_int_t sgn:1, exp:MP_FLOAT_EXP_BITS, frc:MP_FLOAT_FRAC_BITS; } p; + #endif + } u; + u.p.sgn = 0; + u.p.exp = (1 << (MP_FLOAT_EXP_BITS - 1)) - 1; + if (MP_FLOAT_FRAC_BITS <= 32) { + u.p.frc = yasmarang(); + } else { + u.p.frc = ((uint64_t)yasmarang() << 32) | (uint64_t)yasmarang(); + } + return u.f - 1; +} + +STATIC mp_obj_t mod_urandom_random(void) { + return mp_obj_new_float(yasmarang_float()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_urandom_random_obj, mod_urandom_random); + +STATIC mp_obj_t mod_urandom_uniform(mp_obj_t a_in, mp_obj_t b_in) { + mp_float_t a = mp_obj_get_float(a_in); + mp_float_t b = mp_obj_get_float(b_in); + return mp_obj_new_float(a + (b - a) * yasmarang_float()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform); + +#endif + +#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS + +STATIC const mp_rom_map_elem_t mp_module_urandom_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_urandom) }, + { MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&mod_urandom_getrandbits_obj) }, + { MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_urandom_seed_obj) }, + #if MICROPY_PY_URANDOM_EXTRA_FUNCS + { MP_ROM_QSTR(MP_QSTR_randrange), MP_ROM_PTR(&mod_urandom_randrange_obj) }, + { MP_ROM_QSTR(MP_QSTR_randint), MP_ROM_PTR(&mod_urandom_randint_obj) }, + { MP_ROM_QSTR(MP_QSTR_choice), MP_ROM_PTR(&mod_urandom_choice_obj) }, + #if MICROPY_PY_BUILTINS_FLOAT + { MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_urandom_random_obj) }, + { MP_ROM_QSTR(MP_QSTR_uniform), MP_ROM_PTR(&mod_urandom_uniform_obj) }, + #endif + #endif +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_urandom_globals, mp_module_urandom_globals_table); + +const mp_obj_module_t mp_module_urandom = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_urandom_globals, +}; + +#endif //MICROPY_PY_URANDOM diff --git a/python/src/py/mpconfig.h b/python/src/py/mpconfig.h index fb507a503..aca397b97 100644 --- a/python/src/py/mpconfig.h +++ b/python/src/py/mpconfig.h @@ -1044,12 +1044,12 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_URANDOM -#define MICROPY_PY_URANDOM (0) +#define MICROPY_PY_URANDOM (1) #endif // Whether to include: randrange, randint, choice, random, uniform #ifndef MICROPY_PY_URANDOM_EXTRA_FUNCS -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) +#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #endif #ifndef MICROPY_PY_MACHINE