Mini sudoku (4x4) generator efficiency

I have a code that can generate a 4x4 sudoku matrix, by random generation of numbers. To do this, i create a Matrix4 class that can detect its elements by its rows, columns, and submatrices for sudoku puzzle.

The method used here is by inputting a random matrx (4x4) and then shuffle the numbers in (1,2,3,4) to be randomly put in the matrix until it became a solved sudoku matrix.

The sudoku_gen(Matrix,f) will generate a sudoku matrix with Matrix as a Matrix4 object, and f as the frequency for the shuffle.

I intend to only use minimum number of modules,only copy and random are used here.

The weakness is that, it is slow. I would appreciate for feedbacks on this. Thanks.

#### 9 January 2018,
#### Author : Arief Anbiya
#### Description : A code to generate a minimum sudoku-matrix (4x4).
####               The method used is still naive.
####               The emphasis is on the short code,
####               and only two modules used : copy and random.
####               This is my first code uploaded in GitHub

import copy
import random

def shuffle(x, freq):
y = copy.deepcopy(x);
for i in range(0,freq):
idx = int(random.uniform(0, len(x)));
val = y.pop(idx);
y.append(val);
z = copy.deepcopy(y);
return z

class Matrix4:
def __init__(self, matrix):
self.mat = copy.deepcopy(matrix);
self.rows = self.mat;
self.columns = [[i[j] for i in self.rows] for j in range(0, 4)];
sub_1 = [self.rows, self.rows, \
self.rows, self.rows];
sub_2 = [self.rows, self.rows, \
self.rows, self.rows];
sub_3 = [self.rows, self.rows, \
self.rows, self.rows];
sub_4 = [self.rows, self.rows, \
self.rows, self.rows];
self.submats = [sub_1, sub_2, sub_3, sub_4];
def show(self):
print('--Rows--');
print(self.rows);
print('--Columns--');
print(self.columns);
print('--Subgrids--');
print(self.submats);
print('--Matrix--');
for i in self.rows:
print(i);

def checking(matrix):
check = [True, True, True];
for i in matrix.rows:
if len(set(i))!=4:
check = False; break
for i in matrix.columns:
if len(set(i))!=4:
check = False; break
for i in matrix.submats:
if len(set(i))!=4:
check = False; break
print(check);
if False in check:
return False
else:
return True

def sudoku_gen(matrix, f):
store = list(); attempt = int(0);
while not checking(matrix):
while (matrix.rows in store):
Mat = list();
for i in range(0, 4):
Y= shuffle(num, f);
while Y in Mat :
Y = shuffle(num, f);
Mat.append(Y);
matrix = Matrix4(Mat);
store.append(copy.deepcopy(matrix.rows));
attempt = attempt + 1;
print('----'+str(attempt));
return matrix

#f is the frequency of shuffeling to permute list [1, 2, 3, 4].
#This will be used in function shuffle(x, freq) and sudoku_gen(matrix, f).
f = 20;
#You may use different combinations of this parameter.

Mat = list(); num=[1,2,3,4];
for i in range(0, 4):
Y = shuffle(num, f); print(Y);
Mat.append(Y);

Matrix = Matrix4(Mat);
new_mat = list();
new_mat.append(sudoku_gen(Matrix, f));

#This is the number of sudoku-matrix to be generated.
number_of_sudoku = 5;

while len(new_mat)<number_of_sudoku:
repeat = True;
while repeat:
repeat = False;
result = sudoku_gen(Matrix, f);
#Uniqueness test:
for i in new_mat:
if i.rows == result.rows:
repeat = True; break
new_mat.append(sudoku_gen(Matrix, f));
idx = 1;
for i in new_mat:
print('***** Matrix-'+str(idx)+' *****');
idx = idx+1;
i.show();

This code is available on https://github.com/anbarief/sudoku-gen