Deepak Gurumoorthy
Deepak Gurumoorthy

Reputation: 83

Python-randint function without repetition

I am just a beginner to python.And I here just wrote a simple program just to self evaluate myself and try to answer the questions asked in a random order.But the bug here is that the randint function sometimes acquires the same number which was already acquired that I get the same question repeated.I tried my best to fix it but I could n't . Hope I get some help here.`import random

global some
global i
i=0

some=[]
names=['electric charge','permitivity of the medium','permitiovity of free space','relative permitivity of the medium','intensity  of the electric field','electric potential at a point','electric potential energy','dipole moment','torque acting on the dipole','electric flux','linear charge density of the conductor','surface charge density of the conductor','capacitance of a parallel plate capacitor','practical unit of capacitance']
answer=['C','C2N-1m-2','C2N-1m-2','no unit','NC-1 or Vm-1','V','J','Cm','Nm','Nm2C-1','Cm-1','Cm-2','F','uF or pF']
def loop(i):
    for i in range(i,len(names)):
        global qno
        qno=random.randint(0,len(names))
        if i>0:
            for k in range(0,len(some)):
                if str(qno)==some[len(some)-1]:
                    loop(i-1)
        print(names[qno])
        print('Type your answer')
        tell=input()
        if tell==answer[qno]:
            print('Right answer.Move on')
        else:
            print('Wrong answer,.The answer is '+answer[qno])
        for j in range(i+1):
            some.append(str(qno))
i=i+1

loop(i)
`

Upvotes: 1

Views: 450

Answers (4)

f5r5e5d
f5r5e5d

Reputation: 3706

maybe a little advanced, its nice to have options that don't require explicit indexing

import random

names=['electric charge','permitivity of the medium','permitiovity of free space','relative permitivity of the medium','intensity  of the electric field','electric potential at a point','electric potential energy','dipole moment','torque acting on the dipole','electric flux','linear charge density of the conductor','surface charge density of the conductor','capacitance of a parallel plate capacitor','practical unit of capacitance']
answer=['C','C2N-1m-2','C2N-1m-2','no unit','NC-1 or Vm-1','V','J','Cm','Nm','Nm2C-1','Cm-1','Cm-2','F','uF or pF']

# zip, list comprehensions are useful things to learn
# this helps keep things together without explicit index calcs
name_answer_pairs = [(n, a) for n, a in zip(names, answer)]

atest = name_answer_pairs[:] # need a copy, atest gets modified below
random.shuffle(atest)

yes = False

while atest:     # loops until atest is empty, add your UI code to loop
    quest, ansr = atest.pop()   # gets the pair, removes the tuple from the end
    print('Q: ',quest, '\n', 'Ans: ', ansr) # just to show an example

    # do your user Q/A thing here

    # check if atest is empty, to repeat loop with new atest, refresh atest:
    if not atest:
    # ask user to continue?, set 'yes' True or False
        if yes:    
            atest = name_answer_pairs[:]    
            random.shuffle(atest)           # new atest, different order
            continue
        else:
            break

Q:  practical unit of capacitance 
 Ans:  uF or pF
Q:  electric charge 
 Ans:  C
Q:  capacitance of a parallel plate capacitor 
 Ans:  F
Q:  dipole moment 
 Ans:  Cm
Q:  intensity  of the electric field 
 Ans:  NC-1 or Vm-1
Q:  electric potential energy 
 Ans:  J
Q:  permitiovity of free space 
 Ans:  C2N-1m-2
Q:  electric flux 
 Ans:  Nm2C-1
Q:  permitivity of the medium 
 Ans:  C2N-1m-2
Q:  torque acting on the dipole 
 Ans:  Nm
Q:  relative permitivity of the medium 
 Ans:  no unit
Q:  surface charge density of the conductor 
 Ans:  Cm-2
Q:  electric potential at a point 
 Ans:  V
Q:  linear charge density of the conductor 
 Ans:  Cm-1

could be while True:now that I added the if not atest at end of loop

Upvotes: 0

gregory
gregory

Reputation: 12895

If you use randomint(0, 14), you're bound to get lots of repeats! For example:

import random

names=['electric charge','permitivity of the medium','permitiovity of free space','relative permitivity of the medium','intensity  of the electric field','electric potential at a point','electric potential energy','dipole moment','torque acting on the dipole','electric flux','linear charge density of the conductor','surface charge density of the conductor','capacitance of a parallel plate capacitor','practical unit of capacitance']


for i in range(10):
...     print( random.randint(0,len(names)))

Here's my output, on my first run:

12
6
6
6
7
14
7
11
4
10

Notice how I got the number 6 three times! Obviously repeats will happen less as the range increase, but you'll always run a chance of repeating numbers especially since this is only a pseudo random generated number.

Perhaps you're looking for something like shuffle? For example:

>>> new_order = ([ i for i in range(len(names)) ])
>>> random.shuffle(new_order)
>>> print(new_order)
[9, 10, 7, 8, 4, 13, 0, 2, 3, 6, 12, 5, 1, 11]

Upvotes: 0

Alex L
Alex L

Reputation: 1114

The random.shuffle function does exactly what you want.

Upvotes: 1

Adam Venis
Adam Venis

Reputation: 176

before your function, add an array of booleans that describes which questions have already been answered:

already_asked = [False] * len(names)

then, where you assign qno to a value, keep generating random numbers until you've hit one you haven't asked before, and mark the newly asked question as asked:

qno = random.randint(0, len(names))
while already_asked[qno]:
    qno = random.randint(0, len(names))
already_asked[qno] = True

Upvotes: 2

Related Questions