-1

I've created a function which can take a parameter which defines another call to manipulate a list. For example if I call sliprotor(Rotorid1, 1) directly, then the Rotorid1 list is manipulated as I want. Function below:

def sliprotor(rotorid,offset_qty):                          
    for movers in range(26,0,-1):
         rotorid[movers-1+offset_qty]=rotorid[movers-1]     
    for movers_refill in range(offset_qty):
         rotorid[movers_refill]=rotorid[movers_refill+26]   

However, if I try to call this 'indirectly' by building the list name and then executing it, 'rotorid' is not translated to the value, as it is when called directly.

The way I am doing this is

def set_curr_rotor(XX): 
    rotorid = "Rotorid"+str(XX)             
    return rotorid  

rid1 = input("First rotor slip : ")         
if(rid1): 
    sliprotor(set_curr_rotor(rid1),1)

So the 'indirect' call doesn't pass the value created by the set_curr_rotor function into the sliprotor function. The direct call does use the passed in value.

If I look in debug, you can see that it is directly calling rotorid[] as the list, not Rotorid1 or other Rotoridx and hence I get an index error.

.... File "", line 3, in sliprotor rotorid[movers-1+offset_qty]=rotorid[movers-1] IndexError: string index out of range

I could restructure the way I have the code, but I would prefer not to. Is there some method / scope issue I am missing? Is this just an intrinsic attribute of Python? I'm very new to Python so I'm just doing an exercise to model an Enigma machine.

Any help appreciated. Ed

Ed G
  • 1
  • 1
  • 2
    Possible duplicate of [How do I create a variable number of variables?](https://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables) – wwii Sep 18 '17 at 21:50
  • 2
    Don't do this. It is poor design. Use a *container* instead. – juanpa.arrivillaga Sep 18 '17 at 21:50
  • Fundamentally, *don't mix up your string objects with variable names*. You can use all sorts of sorcery to do this, but again, it's very, very bad practice. – juanpa.arrivillaga Sep 18 '17 at 21:51
  • Keep your lists in a dictionary. Then you can cunstruct keys as strings to access the lists in the dictionary. – wwii Sep 18 '17 at 21:54
  • I'll look at using a dictionary of lists. Thanks – Ed G Sep 18 '17 at 21:59

1 Answers1

1

I'll assume that you have defined your rotors already, something like this:

Rotorid1 = list('abcdefghijklmnopqrstuvwxyz')
Rotorid2 = list('abcdefghijklmnopqrstuvwxyz')

And now you're reluctant to change this, because ... reasons.

That's fine. But you're still wrong. What you need to do is to create a larger data structure. You can do it like this:

Rotors = [ Rotorid1, Rotorid2, ... ]

Now you have a list-of-lists. The Rotors variable now contains all the various Rotorid variables. (Well, it references them. But that'll do.)

Instead of passing in the variable name as a handle to the rotor, you can simply pass in an index number:

def set_rotor(id):
    global Current_rotor
    Current_rotor = id

def slip_rotor(amount):
    global Current_rotor
    global Rotors

    rotor = Rotors[Current_rotor]

    for movers in range(26,0,-1):
        rotor[movers-1+offset_qty]=rotor[movers-1]      
    # etc...

Also, be sure an look up slicings in Python - you can do a lot by manipulating sublists and substrings using slices.

aghast
  • 14,785
  • 3
  • 24
  • 56
  • If he is having problems with the dictionary index (or list) , I think that it would be useful to check if the element exist in the list (or the key exists in the dict) – Jason Jiménez Sep 18 '17 at 22:02
  • Hi thanks for the reply. Actually my rotors are lists of lists, but I have no philosophical objection to changing them. I'll be doing that. It really was just a question to confirm that what I was attempting was not supported, and it's not, so I'll look at alternatives. – Ed G Sep 20 '17 at 08:04
  • OK, so I think my basic assumptions about what you can or cant do within python lists of lists are wrong. You cant seem to retrieve a name held within one list as a reference for another list. i.e. if I have top_list = [l1,l2,l3] and l1=[[i11,i12,i13],[i21,i22,i23],[i31,i32,i33]], l2=[[m11,m12,m13],[m21,m22,m23],[m31,m32,m33]], l3= [[o11,o12,o13],[o21,o22,o23],[o31,o32,o33]] and I refer to top_list[0] I cannot use that as a reference to l1 which allows me to access the lists within it. – Ed G Sep 21 '17 at 19:33
  • You can, if you are storing references. You don't want to be storing literal strings. – aghast Sep 21 '17 at 19:45
  • I'll create a 3 deep list of lists. – Ed G Sep 21 '17 at 19:55