Jump to content

5 Digit Number Generator Problem


Recommended Posts

Hey,

I am making a small function that will be used within a database application and it should generate a random 5 digit number, however if the number already exists within a text file then it will create another number instead so you never get the same number twice. At the moment the program won't regenerate the number if its already been generated and I can't figure out why. ;)

; Generates a random 5 digit Customer ID with 100,000 possible combinations.
; Declare Variables
$IDLength = 0
$ID = ""
$Line = 1
; End Of Decleration
GenerateID() ; Begin Function
Func GenerateID() ; Function creates a 5 digit customer ID.
Do
   $ID = $ID & Random(0, 9, 1)
   $IDLength = $IDLength + 1
Until $IDLength = 1 ; Usually 5 but set to 1 for testing purposes.
EndFunc
If Not FileExists(@ScriptDir & "\Customer ID.txt") Then
FileWrite("Customer ID.txt", $ID & @CRLF) ; If database doesent exist write ID to new database.
Exit
EndIf
$ReadFile = FileOpen(@ScriptDir & "\Customer ID.txt", 1) ; Set file up for reading and writing use.
Do
$IDReturn = FileReadLine($ReadFile, $Line) ; Read line of database.
If $IDReturn = $ID Then
   GenerateID() ; If return ID = generated ID then generate another.
Else
   $Line = $Line +1 ; Else add 1 to the variable line so the file reads the next line.
EndIf
Until @Error = -1 ; Carry out this loop until readfile returns no line.
FileWrite("Customer ID.txt", $ID & @CRLF) ; If program passes through this loop then add customer ID to database.
Link to comment
Share on other sites

This script can generate random ID's between 100 to 999 (and will generate another number if it exists in mkk.txt):

Func _GenRandomId()
$RANDOM = Random(100, 999, 1)
If StringInStr(FileRead("mkk.txt"), "" & $RANDOM) then
return msgbox(64, "Number ID", Random(100, 999, 1))
else
return msgbox(64, "Number ID", $RANDOM)
EndIf
EndFunc
$TIMER = TimerInit()
While 1
If TimerDiff($TIMER) > 10000 then Exit
_GenRandomId()
WEnd
Edited by MKISH

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Link to comment
Share on other sites

And what's wrong with using the DB engine's rowid (identity, autoincrement ID, call it whatever)?

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Bah, I wish jchd hadn't said that. Well I might as well post this anyway. Incidentally I picked up some tips from jchd to create this code. ;)

#include <String.au3>

Dim $aNumbers[100000]
For $i = 0 To 99999
    $aNumbers[$i] = $i ; Each element is given a unique value
Next

_RandomSwap($aNumbers) ; Randomize the order of elements

For $i = 0 To 99 ; Print out the first 100 values
    $iLen = 5 - StringLen($aNumbers[$i])
    If $iLen Then $aNumbers[$i] = _StringRepeat("0", $iLen) & $aNumbers[$i] ; Prefix zeros if necessary
    ConsoleWrite($aNumbers[$i] & @LF)
Next

Func _RandomSwap(ByRef $aArray)
    Local $vTemp
    For $i = 0 To 99999
        $j = Random(0, 99999, 1)
        If $j <> $i Then ; Swap the elemeents randomly
            $vTemp = $aArray[$i]
            $aArray[$i] = $aArray[$j]
            $aArray[$j] = $vTemp
        EndIf
    Next
EndFunc
Edited by czardas
Link to comment
Share on other sites

Which DB engine do you plan to use?

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Which DB engine do you plan to use?

No perticular engine in mind i am just going to be displaying the information in a list veiw, by database i pretty much just meant saving to a text file then reading it later on through the use of list veiw. Sorry if i didn't make that clear.

Thanks for all the samples posted by the way I will be looking through them and using the method that works best for me.

Edited by Venix
Link to comment
Share on other sites

Ah OK, sorry for interpreting DB as DB Posted Image

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

  • 4 months later...

Hello is there a way to have the random number that is generated not create the mkk.text but to have it open up to a label somethig that

that can be cut and pasted or copied after the number is generated.

Func _GenRandomId()

$RANDOM = Random(100, 999, 1)

If StringInStr(FileRead("mkk.txt"), "" & $RANDOM) then

return msgbox(64, "Number ID", Random(100, 999, 1))

else

return msgbox(64, "Number ID", $RANDOM)

EndIf

EndFunc

$TIMER = TimerInit()

While 1

If TimerDiff($TIMER) > 10000 then Exit

_GenRandomId()

WEnd

Link to comment
Share on other sites

Venix,

There are several problems with your origional code. I've noted some of them in the comments

; Generates a random 5 digit Customer ID with 100,000 possible combinations.
; Declare Variables
$IDLength = 0
$ID = ""
$Line = 1
; End Of Decleration
GenerateID() ; Begin Function
Func GenerateID() ; Function creates a 5 digit customer ID.
Do
   $ID = $ID & Random(0, 9, 1)
   $IDLength = $IDLength + 1
Until $IDLength = 1 ; Usually 5 but set to 1 for testing purposes.
EndFunc
;
; in the next two lines you are testing for file @scriptdircustomer id.txt but writing to file = customer id.txt.
; This may work as the current dir is the script dir, however, it is ambiguos at best.
;
If Not FileExists(@ScriptDir & "Customer ID.txt") Then
FileWrite("Customer ID.txt", $ID & @CRLF) ; If database doesent exist write ID to new database.
Exit
EndIf
;
; you are opening the file for for output with append and then trying to read it
; $idreturn does not contain what you think it does, consequently, your logical test will never be valid
; run the following code with a consolewrite to demonstrate this
;
$ReadFile = FileOpen(@ScriptDir & "Customer ID.txt", 1) ; Set file up for reading and writing use.
Do
$IDReturn = FileReadLine($ReadFile, $Line) ; Read line of database.
consolewrite('+ $idreturn = ' & $idreturn & @lf)
If $IDReturn = $ID Then
   GenerateID() ; If return ID = generated ID then generate another.
Else
   $Line = $Line +1 ; Else add 1 to the variable line so the file reads the next line.
EndIf
;
;  @error can be set by any function.  ALWAYS test immediately following whatever function you are testing for, or, save @error in another variable.
;
Until @Error = -1 ; Carry out this loop until readfile returns no line.
FileWrite("Customer ID.txt", $ID & @CRLF) ; If program passes through this loop then add customer ID to database.

If I were going to do this using a flat file I would do it like this

;
;
;
local $IDLength = 1
local $id = GenerateID()
local $fl_name = @ScriptDir & "Customer ID.txt"
If Not FileExists($fl_name) Then
 FileWrite($fl_name, generateid() & @CRLF)
 Exit
EndIf
local $IDReturn = FileRead($fl_name)
if @error = 1 then msgbox(0,'','Severe Error...exiting')
while 1
 if stringinstr($idreturn,$id) = 0 then exitloop
 $ID = GenerateID()
wend
local $hfl = fileopen($fl_name,1)
FileWrite($hfl, $ID)
fileclose($hfl)
Func GenerateID()
 $id = ""
 for $i = 1 to $idlength
  $ID &= Random(0, 9, 1)
 next
 return $id & @crlf
EndFunc

Good Luck,

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

While I thank you for giving good feedback on an old topic of mine and I have read through your reply. This topic was dead some time ago, let’s leave it like that. :D

:rip:

Edited by Venix
Link to comment
Share on other sites

Another Attempt

#include <Array.au3>

Global $aNumbers
Local $aDisplay[1],$iDimension,$iCount
Local $t=TimerInit()
For $n=0 To 1000
_ArrayAddEx($aDisplay, _ ;Add array without wasting much time
_RandomEx() _ ; Randomize without Repetition
,$iDimension,$iCount) ;The Rest Parameters of _ArrayAddEx
Next
ConsoleWrite('Timer:'&TimerDiff($t)&@CR)
ReDim $aDisplay[$iCount]
_ArrayDisplay($aDisplay)

Func _RandomEx($nDigits=5)
Local $vTemp=Random(10^$nDigits,(10^($nDigits+1))-1,1)
Local $iUBound=UBound($aNumbers)
Static $nRecCheck=0
;If Recursion Exceeds above 100 not possible in 5digits numbers then Return
If $nRecCheck>100 Then Return SetError(1,0,-1)
For $i=0 To $iUBound-1
Switch $aNumbers[$i]
Case $vTemp
$nRecCheck+=1
Return _RandomEx($nDigits)
EndSwitch
Next
$nRecCheck=0
If Not IsArray($aNumbers) Then
Local $n[1]=[$vTemp]
$aNumbers=$n
Else
_ArrayAdd($aNumbers,$vTemp)
EndIf
Return $vTemp
EndFunc ;==>_RandomEx

Func _ArrayAddEx(ByRef $aArray, $sData, ByRef $iDimension, ByRef $iCount) ; Taken from Array.au3 and modified by guinness to reduce the use of ReDim.
If IsArray($aArray) = 0 Then
Return SetError(1, 0, -1)
EndIf
If UBound($aArray, 0) <> 1 Then
Return SetError(2, 0, -1)
EndIf
If $iCount = 0 Then
$iCount = UBound($aArray, 1)
EndIf
$iCount += 1
If ($iCount + 1) >= $iDimension Then
$iDimension = (UBound($aArray) + 1) * 2
ReDim $aArray[$iDimension]
EndIf
$aArray[$iCount - 1] = $sData
Return $iCount - 1
EndFunc ;==>_ArrayAddEx
Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

@scsicard65 - You might want to open a new thread with your question. Your attempt at hijacking this older thread has, so far, only lead to responses to the original post.

Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Link to comment
Share on other sites

I feel like your code is going to generate a parallel universe and not 5 numbers.

If you feel so here is the Iterative version without the use of Recursions..

this is probably more easy with the use of Arrays

if you need to use it with File, you can read the file and add the corresponding values to an array

#include <Array.au3>

Global $aNumbers

Local $t = TimerInit()
For $n = 0 To 1000
_RandomEx(); Randomize without Repetition
Next
ConsoleWrite('Timer:' & TimerDiff($t) & @CR)
_ArrayDisplay( $aNumbers)


Func _RandomEx($nDigits = 5);Converted from Recursive to Iterative
;All the Possible Numbers have been added return -1 and set @error
If UBound($aNumbers)>=(10 ^ $nDigits)-1  Then Return SetError(1,0,-1)

Local $vTemp
While 1
$vTemp = Random(10 ^ ($nDigits-1), (10 ^ $nDigits) - 1, 1)
_ArraySearch($aNumbers,$vTemp)
If @error Then ExitLoop
WEnd
If Not IsArray($aNumbers) Then
;Make it an Array
Local $n[1] = [$vTemp]
$aNumbers = $n
Else
_ArrayAdd($aNumbers, $vTemp)
EndIf
Return $vTemp
EndFunc   ;==>_RandomEx

#cs
Some More Description

If a loop of 1000 is used when the number of digits would be set to 2
then a lot of time would be taken because
upon reaching 90 only 9 numbers would be left and hence the
probability of triggering any of the remaning 9 numbers is very less.

Solution: use the loop with the maximum limit set to somewhat less than the number of digits

Another Solution: a probability check could also be used, if required please ask.. :)
#ce

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

Was just kidding with you Phoenix but this looks like a much cleaner version anyhow. When I was attempting to make it some time ago now I did not think of using the ^ sign.

Edited by Venix
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...