HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

An enigma style simulation machine in Python 3

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simulationstylepythonmachineenigma

Problem

This code made a few breaks back in my spare time. There are, however, a few alterations to the original machine that this simulation shows, one being the alphabet, another being the amount of rotors.

```
from random import *
import msvcrt
import os
from os import walk
english = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',',','.','?','-','+','=','1','2','3','4','5','6','7','8','9','0',' ','\'','"','!']
def diskgen(alphabet):
#DISK GENERATION
disk_avail = []
disk_direc = []
disk_map = []
for num in range (0,len(alphabet)):
disk_avail.append(num)
disk_direc.append(num)
#Begin mapping
while len(disk_direc) > 0:
choose_ep = randint(0,len(disk_avail)-1)
exit_position = disk_avail[choose_ep]
disk_map.append(exit_position)
del disk_avail[choose_ep]
del disk_direc[0]
for pos in range (0,len(alphabet)):
disk_map[pos] = disk_map[pos] - pos
return disk_map
def reflector(alphabet):
reflect_avail = []
reflect_map = []
for num in range (0,len(alphabet)):
reflect_avail.append(num)
reflect_map.append('x')
if len(reflect_avail)%2 == 0:
while len(reflect_avail) > 0:
from_num = reflect_avail[0]
to_pos = randint(1,len(reflect_avail)-1)
fin_num = reflect_avail[to_pos]
reflect_map[from_num] = fin_num
reflect_map[fin_num] = from_num
del reflect_avail[0]
del reflect_avail[to_pos-1]
for pos in range (0,len(alphabet)):
reflect_map[pos] = reflect_map[pos] - pos
return reflect_map
def rotate(selected_disk):
new_disk = []
new_disk.append(selected_disk[len(selected_disk)-1])
for pos in range (0,len(selected_disk)-1):
new_disk.append(selected_disk[pos])
return ne

Solution

Here are some things related to performance and the code quality in general:

  • what the diskgen() and reflector() functions do, does not really depend on the user's input and can be pre-computed to avoid wasting time during the runtime. Create the disk and reflector maps beforehand.



  • to multiply the disk mappings, use copy.deepcopy() instead of regenerating the mapping



-
the rotation code can be improved by using slicing - might also be faster:

def rotate(disk):
    return [disk[-1]] + disk[:-1]


-
note the use of negative indexing and list slicing (you can apply these things in other parts of the code - it would not only make the code more concise and readable, but may provide performance boosts)

-
you can make use of *args and **kwargs to pass around multiple arguments

-
make use of unpacking, e.g. you can improve the way you parse the information list (splited to multiple slices for readability):

d1, d2, d3, d4 = information[:4]
rf = information[4]
d1rc, d2rc, d3rc, d4rc = information[5:9]
rfrc = information[9]


-
use list and dictionary comprehensions

  • put the main program logic to under the if __name__ == '__main__':



  • extract the user input part into a separate function



-
the english list can be defined as a concatenation of sets of characters available in the string module:

In [1]: import string

In [2]: string.ascii_letters
Out[2]: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'


Code organization-wise, the code really asks for a class (of course, you don't have to write classes), say, Machine in which, the constructor method will be responsible for initializing disks and reflectors, the disks would be instance variables - you would simply access them via self.diskN instead of passing around from method to method. The rotation logic at the end of the program should also be extracted and be a part of this class.

Code Snippets

def rotate(disk):
    return [disk[-1]] + disk[:-1]
d1, d2, d3, d4 = information[:4]
rf = information[4]
d1rc, d2rc, d3rc, d4rc = information[5:9]
rfrc = information[9]
In [1]: import string

In [2]: string.ascii_letters
Out[2]: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

Context

StackExchange Code Review Q#155281, answer score: 3

Revisions (0)

No revisions yet.