×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

How do I allot prizes to a person on different dates?

How do I allot prizes to a person on different dates?

How do I allot prizes to a person on different dates?

(OP)



I tried using Rand() but I am failing in implementing something like this, where I randomly give the employees prizes on random dates while also having control and constraining the number of prizes an employee can get.
I have only used and seen/understand old foxpro codes so I will appreciate If any one can help with writing a function for this. Please.

( I have attached a picture just if I am not able to explain my question )

RE: How do I allot prizes to a person on different dates?

It would help to know where you are starting from. In other words, do you already have your data in tables (DBF files) or arrays? If so, what data do you have? And what are your rules for giving prizes? For example, how far in advance do you want to assign a prize? Can an employee get prizes on two consecutive dates? Is the amount of the prize also random, or is it always the same amount? And so on. (I'm not asking for the answers to those questions. I am just giving examples of the sort of rules that you must establish.)

But to get things started, let's assume that you have an employee table, like this:

CODE -->

ID     Name
==     ====

10     Andy
25     Bonny
36     Darren 

Create a prizes table, like this:

CODE -->

ID    Employee_ID     Prize_Date   
==    ===========     ========== 

Your code would look something like this:

CODE -->

* Asumes you want to give prizes up to 30 days in advance; 
* Prizes table has auto-incrementing ID; the amount
* of the prize is fixed.
SELECT Employee
SCAN
  INSERT INTO Prizes (Employee_ID, Prize_Date) ;
    VALUES (Employee.ID, DATE() + INT((RAND() * 30)))
ENDSCAN 

This is only meant to give you a start. You will probably need to refine it according to the rules mentioned above.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

(OP)
I created both the tables, Employee and Prizes
=================
Employee table having
ID -> numeric -> 2
Name -> character -> 10
=================
======================
Prizes table having
ID -> numeric -> 2
Employe_ID -> numeric -> 2
P_date -> numeric -> 8
=======================

I populated the table Employee with data and tried to run the program but an error persist on

CODE

INSERT INTO Prizes (Employe_ID, P_Date) ;
    VALUES (Employee.ID, DATE()+ INT((RAND() * 30)))] 

showing DATA TYPE MISMATCH
I am not able to figure out what is the mismatch ?

RE: How do I allot prizes to a person on different dates?

The "Data type mismatch" happened because your P_date field is numeric. It should be a Date field. Change it to a Date data type, and that will get you past that error.

Regarding the "500 prize money", do you mean that each prize is worth 500? If so, there is no need to store the amount in a table. It will be the same for all employees.

In any case, my code was not meant to be a complete solution. As I explained at the start, we would need a lot more information to provide that. My aim was to give you a start, to help you to understand the general approach so that you can solve the problem for yourself.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

(OP)
Instead of randomly assigning numeric values or dates, how can i just allot a character like 'W' ?

RE: How do I allot prizes to a person on different dates?

I don't know what you mean. As Mike already said about the amount of 500, it's not necessary to allot anything but the winning date to an employee, if the prize is fixed.

Later display W in a grid at the dates you have in data, ot 500, or whatever.

If you want that flexible, well, then add fields to the table and populate them as necessary. A char(1) field could store a 'W' or any other ANSI character in the DBF codepage. For amounts you can add an integer field, or currency.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How do I allot prizes to a person on different dates?

(OP)
I just want to clear things, if there are fields in prize tables as
-------------------------------------------------------------------
employee.id | one | two | three | four | and so on... to thirty |
-------------------------------------------------------------------
if I define a variable mWon = 'W' and write a function which which tells that the "W" character needs to appear 4 times in random fields like :

-----------------------------------------------------------------------------------------
employee.id | one | two | three | four | five | six | seven | eight | nine | ten | .....
001..............| W | ..........| W | ...........| W | |...| |...| .......| W | .....
-----------------------------------------------------------------------------------------

I wanted to convey and needed to understand how can I achieve this ( also tried to explain this same thing with a picture ) with a help of old foxpro codes!

I sincerely apologies if I am not clear in making my question more easier.
Hope this helps.

RE: How do I allot prizes to a person on different dates?

Ok, that's a thing you wouldn't do knowing how to normalize your data, what you describe as data structure is 1:1 what you would want to display in a grid but not store that way, it's candidate for a record per cell.

Ynway, I can't guarantee you this works in legacy foxpro, but there is field(n) so when you know the fields in question are field number 2 to 32 (because employee id is beforehand). then generate a number between 1 and 31 for the day and lookup field name with the field() function, field(randimnumber+1) will pick one of the field names of fields 2 to 32. And then put the value into that with REPLACE.

CODE

REPLACE (field(randomnumber+1)) WITH 'W' 

for example.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How do I allot prizes to a person on different dates?

Janak, as Olaf has pointed out, what you are now describing is a terrible data structure. It will be inefficient and difficult to query. However, if that is what you want, you can do something like this:

First, name all the fields (except Employee ID) something like F1, F2, F3, and so on, up to F30. Then do this:

CODE -->

SELECT Prizes
SCAN
  lcField = "F" + (INT(RAND() * 30))
  REPLACE &lcField WITH "W"
ENDSCAN 


That will place a W in a random field for each employee. It won't deal with any constraints, such as the maximum number of prizes one employee can win, or whether prizes can be awarded on consecutive dates.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

You said you are using old Foxpro code. I don't know how far back you are going, but if your version doesn't support SCAN / ENDSCAN, then do this instead:

CODE -->

SELECT Prizes
GO TOP
DO WHILE NOT EOF()
  lcField = "F" + (INT(RAND() * 30))
  REPLACE &lcField WITH "W"
  SKIP
ENDSCAN 


Essentially it's the same thing, but just with a different way of looping through the table.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

Just to illustrate you don't need 30 fields when you want to sparsely populate 30 columns:

CODE

Create Cursor crsLottery (winnercolumn int)
Insert into crsLottery values (Int(Rand()*5+1))
Insert into crsLottery values (Int(Rand()*5+1))
Insert into crsLottery values (Int(Rand()*5+1))
Insert into crsLottery values (Int(Rand()*5+1))
Insert into crsLottery values (Int(Rand()*5+1))
Insert into crsLottery values (Int(Rand()*5+1))

Browse fields ;
w1=Iif(winnercolumn=1,'W',' '),;
w2=Iif(winnercolumn=2,'W',' '),;
w3=Iif(winnercolumn=3,'W',' '),;
w4=Iif(winnercolumn=4,'W',' '),;
w5=Iif(winnercolumn=5,'W',' ') 

You can concentrate on the essential data, just the column number, the date or whatever is necessary to know what column needs to display something.

Sparse data like yours is actually a reason for specific sparse column data structures in NoSQL databases.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How do I allot prizes to a person on different dates?

(OP)
Thank you Olaf and Mike for your valuable insights!
Because of your codes I got a start

CODE -->

CLOSE ALL

SELECT A

        USE MTHDES
        GO MTO
        FL= 'S' + MTH_NO+SUBSTR(COCD,1,3)+ TDYEAR+ '.DBF'
        USE  '&FL'

SELECT B

        USE PRIZES

 
SCAN

REPLACE b->employe_id WITH a->emp_no

endscan


scan



FOR mCounter = 1 TO 5 STEP 1

 nFIELD=Int(Rand() * 33 + 3)  &&... Random number between 1 and 31

REPLACE (field(nFIELD+1)) WITH 'A'    

*EXIT
*LOOP
ENDFOR 

ENDSCAN 
CLOSE ALL


USE PRIZES

BROWSE FONT 'ARIAL BOLD',11 


This is where I am right now



It randomly allots 'A' to only 5 fields. Basically what I wanted to get started with.

What weird is happening is that I sometimes get an syntax error ( what's weird is it only comes a few times and when it comes it messes with the table allotting 6 or 7 'A') error line being :

CODE -->

nFIELD=Int(Rand() * 33 + 3)  &&... Random number between 1 and 31 


I cannot see what is the syntax error is here?
can someone please point it out to me?

RE: How do I allot prizes to a person on different dates?

RAND itself is between 0 and 1, guaranteed not exactly 1, so the number you generate are from 0 to 32, then you add 3 and generate numbers between 3 inclusive up to 36 exclusive, so effectively 3 to 35.

If you want numbers 1 to 31 you have to use INT(RAND()*31+1), if you then need an offset of fields before the first one you want to allot randomly, then add that offset again, but don't multiply RAND()*33 if you want a range of 31 numbers.

If you don't want surprises because of leaving valid numbers just ensure the range is correct by making a lot more experiments:

CODE

* inint min with out of bound numbers:
minnum = 9999
maxnum = -9999

for experiment = 1 to 10000
   number = Int(Rand() * 33 + 3)  && put in your guess of the correct formula
   if minnum > number
      minnum = number
   endif
   if maxnum < number 
      maxnum = number
   endif
endfor 

? "numbers generate d are from ", minnum," up to ", maxnum 

I can tell you your factor and offset bring you from 3 to 35. As said, you may need a range starting at 3 or higher, depending on what number the first field has, you want to allot values to. Your definition of the table does not have the first field of your range of randomizable fields as field number 1, that has to be adjusted. But no matter what that offset is, the factor of RAND(U) will always be the count of different numbers you want to generate. multiply by 33 and you get 33 different numbers. In theory even 10000 experiments won't guarantee you to find the max and min, but given a small enough range and how random numbers of RAND() are distributed this should give you a hint, if it's hard to imagine the extreme values of a formula to you.

The final truth about tests is reveled here: They can reveal a flaw, they can't guarantee clean or working code. So better learn the effective outcome of your formula: INT(RAND()*N)+1 will go from 1 to N, when you need N different numbers starting from 5 instead of 1 then you want the range 5 to N+4 and that will still mean multiply by N, only add 5 instead of 1, only the offset changes.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How do I allot prizes to a person on different dates?

Janak, regarding your syntax error. Are you sure this is a syntax error? What is the actual message that you see? The reason I ask is that you would not normally expect a syntax error to be intermittent. If the syntax is wrong, the statement can never be executed. (An exception to that would be if the statement contains a macro, but that's not the case here.)

Also, are you sure it is that statement that is causing the error? Off-hnad, I can't see anything wrong with its syntax.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

Mike,

there is the possibility of an intermittant syntax error in a line using (field(n)) as name expression, when field(n) for an n outside the range of actually field count doesn't error but results in an empty string or NULL.

Then actually the syntax of the effective code line is having NULL or a missing name, only then, and causes an intermittant syntax error.

The essence is you need to use the right random number formula to remain in the right range of fields.

Just checking an example:

CODE

Create Cursor onefield(f1 i)
Append Blank
Replace (Field(1)) with 42
? f1
Replace (Field(2)) with 42 

Yes, using field(2) in a single field workaea leads to an intermittant syntax error and no compilation error. VFP is extremely forgiving about macro substitution and name expressions and does not even do the simplest checks at compiletime. In this case the compiler can't see and know that the active workarea will have only one field at runtime. Indeed you could see this cursor just generated 4 lines above the replace of (field(2)) means this will lead to a syntax error at runtime, but the compiler does not use AI intelligence to deduct that.

Using macro substitution makes it even less predictable to the compiler.

Anyway, there is your intermittent syntax error, this exists and is a possible runtime error, not just a compile time error, due to both macro substitution and name expressions. They can go wrong at runtime.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How do I allot prizes to a person on different dates?

Olaf, I can't reproduce the error you described. I created a cursor with three fields, added a record, and then tested the contents of FIELD(1), FIELD(12), FIELD(0), FIELD(2.5) and FIELD(-1). I couldn't see a syntax error in any of the cases. I then repeated the test with a single-field cursor - as in the code you posted. Again, no syntax error.

I did get an error when passing NULL to FIELD(). But that was an invalid argument type rather than a syntax error.

Still, I take your point that the error was intermittent. I didn't think that was possible in the case of a syntax error, as the statement would have been rejected at compile time. But I'm willing to admit I might be wrong.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

(OP)

CODE -->

CLOSE ALL
SELECT A

        USE MTHDES
        GO MTO
        FL= 'S' + MTH_NO+SUBSTR(COCD,1,3)+ TDYEAR+ '.DBF'
        USE  '&FL'

 SELECT B

        USE PRIZES

 
SCAN
 REPLACE b->employe_id WITH a->emp_no
endscan

*///////////////////////////////////////////////////////////////

scan

FOR mCounter=  1 TO 4

nFIELD=Int(Rand() * 34+4) 

lcField = nField


minnum = 4
maxnum = 34


*//////////////////////////////////////////////////RANDOM CONTROLS////////////////////////////////////////////

if lcfield>=maxnum 
      lcfield=maxnum 
endif


*////////////////////////////////////////////////RANDOM CONTROL OVER////////////////////////////////////////



WAIT WINDOW lcField

REPLACE (field(lcfield)) WITH 'A'  

ENDFOR 

ENDSCAN 
CLOSE ALL

USE PRIZES

BROWSE FONT 'ARIAL BOLD',11

REPLACE ALL D4 WITH ' ',  D5 WITH ' ',   D6 WITH ' ', D7 WITH ' ', D8 WITH ' ', D9 WITH ' ', D10 WITH ' ', D11 WITH ' ', D12 WITH ' ', D13 WITH ' ', D14 WITH ' ', D15 WITH ' ', D16 WITH ' ', D17 WITH ' ', D18 WITH ' ', D19 WITH ' ', D20 WITH ' ', D21 WITH ' ', D22 WITH ' ', D23 WITH ' ', D24 WITH ' ', D25 WITH ' ', D26 WITH ' ', D27 WITH ' ', D28 WITH ' ', D29 WITH ' ', D30 WITH ' ', D31 WITH ' ' , D32 WITH ' ' , D33 WITH ' ' , D34 WITH ' ' 



Having read Olaf answer and changing the offset I now got rid of the syntax error!
What I think was the reason ( with my small lay-man knowledge ) of the syntax error was the lcField going out of bound, having no structure of that number was letting the syntax error.

What I am failing now is that although the FOR loop runs 4 times whenever the lcField is duplicate (i.e. there are two same random numbers ) it only allots
three A's.
Is there any way to control this type of behavior ?
I read something about SYS(2015) function is this of any use here ?

RE: How do I allot prizes to a person on different dates?

Quote:

I read something about SYS(2015) function is this of any use here ?

I doubt it. SYS(2015) returns a name that is guaranteed to be unique within your session. This has a number of uses, but it has nothing to do with generating random numbers.

I don't know what you read or where you read it. I'd suggest you refer to the official VFP help file, which contains the definitive information.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How do I allot prizes to a person on different dates?

(OP)
So how do I go around the duplicate numbers?
If in the iterations duplicate numbers are there there would only be 3 results while The iteration runs for 4 times.

I needed 4 results every time whether there be a duplicate or not.

RE: How do I allot prizes to a person on different dates?

(OP)
the rand() should not generate same numbers, it should generate every time a unique number between range 4 to 34 ! how to work this? please help

RE: How do I allot prizes to a person on different dates?

Mike, I fear I can't help you reproduce the error, but just calling FILED(0) or such doesn'T error, it's the use of an empty string as a field name that causes the final syntax error, I don't know why that would differ under any circumstance. REPLACE (field(200)) WITH 42. Nothing?

Do you have an error handler on, suppressing or just silently logging errors?

Jamak,

the usual practice to get an exact amount of different random numbers is not going with other generators, you can't adjust the behaviour to get next N numbers not overlapping.
As you have lots of empty cells at the end I'd rather turn the for loop counter back 1 and repeat the loop once more, whenever field(X) already has its 'W' allotted, so check that before the REPLACE.

The simplest always working solution that will be better in cases you would want to pick 100% of all items just in random order is to use the random number to pick one item of a list of not already picked items and reduce that list during the process. So no item can be fetched twice or no day allotted twice. That also means your number range will get 1 shorter every time.

That's taking a little bit more effort in VFP. Using a cursor and DELETE rows you're faced with the deletion marking. RECCOUNT() won't drop by 1, the RECNO() you delete only will get a deleted() status. So you'd need to use other mechanisms like a collection or array you can really reduce. But it's overkill for your case, just repeat until you have hit enough empty cells.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How do I allot prizes to a person on different dates?

Quote:

Do you have an error handler on, suppressing or just silently logging errors
?

No. I was just running these tests in the command window, with no other code active. But it's not important. I see that he has got past the syntax error now.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close