generate.py
来自「这是一个用与生成数据库测试文件的程序对于网站的测试有很大的帮助」· Python 代码 · 共 1,725 行 · 第 1/5 页
PY
1,725 行
'val_swap_prob':0.01,
'wrd_swap_prob':0.02,
'spc_ins_prob':0.02,
'spc_del_prob':0.02,
'miss_prob':0.01,
'new_val_prob':0.01}
postcode_dict = {'name':'postcode',
'type':'freq',
'char_range':'digit',
'freq_file':'data'+os.sep+'postcode-freq.csv',
'select_prob':0.05,
'ins_prob':0.00,
'del_prob':0.00,
'sub_prob':0.35,
'trans_prob':0.60,
'val_swap_prob':0.03,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.01,
'new_val_prob':0.01}
state_dict = {'name':'state',
'type':'freq',
'char_range':'alpha',
'freq_file':'data'+os.sep+'state-freq.csv',
'select_prob':0.05,
'ins_prob':0.10,
'del_prob':0.10,
'sub_prob':0.55,
'trans_prob':0.02,
'val_swap_prob':0.03,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.10,
'new_val_prob':0.10}
dob_dict = {'name':'date_of_birth',
'type':'date',
'char_range':'digit',
'start_date':(01,01,1900),
'end_date':(31,12,1999),
'select_prob':0.10,
'ins_prob':0.00,
'del_prob':0.00,
'sub_prob':0.50,
'trans_prob':0.30,
'val_swap_prob':0.05,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.10,
'new_val_prob':0.05}
age_dict = {'name':'age',
'type':'freq',
'char_range':'digit',
'freq_file':'data'+os.sep+'age-freq.csv',
'select_prob':0.05,
'ins_prob':0.00,
'del_prob':0.00,
'sub_prob':0.30,
'trans_prob':0.20,
'val_swap_prob':0.20,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.20,
'new_val_prob':0.10}
phonenum_dict = {'name':'phone_number',
'type':'phone',
'char_range':'digit',
'area_codes':['02','03','04','07','08'], # Australian area codes
'num_digits':8, # For Australian phone numbers
'select_prob':0.05,
'ins_prob':0.00,
'del_prob':0.00,
'sub_prob':0.40,
'trans_prob':0.30,
'val_swap_prob':0.15,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.05,
'new_val_prob':0.10}
ssid_dict = {'name':'soc_sec_id',
'type':'ident',
'char_range':'digit',
'start_id':1000000,
'end_id':9999999,
'select_prob':0.05,
'ins_prob':0.00,
'del_prob':0.00,
'sub_prob':0.50,
'trans_prob':0.40,
'val_swap_prob':0.10,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.00,
'new_val_prob':0.00}
# Create a field which can be used for blocking (generate values 0 to 9 which
# are not modified in duplicates).
#
blocking_dict = {'name':'blocking_number',
'type':'ident',
'char_range':'digit',
'start_id':0,
'end_id':10,
'select_prob':0.00,
'ins_prob':0.00,
'del_prob':0.00,
'sub_prob':0.00,
'trans_prob':0.00,
'val_swap_prob':0.00,
'wrd_swap_prob':0.00,
'spc_ins_prob':0.00,
'spc_del_prob':0.00,
'miss_prob':0.00,
'new_val_prob':0.00}
# -----------------------------------------------------------------------------
# Probabilities (between 0.0 and 1.0) for swapping values between two fields.
# Use field names as defined in the field directories (keys 'name').
field_swap_prob = {('address_1', 'address_2'):0.02,
('given_name', 'surname'): 0.05,
('postcode', 'suburb'): 0.01}
# -----------------------------------------------------------------------------
# Probabilities (between 0.0 and 1.0) for creating a typographical error (a new
# character) in the same row or the same column. This is used in the random
# selection of a new character in the 'sub_prob' (substitution of a character
# in a field).
single_typo_prob = {'same_row':0.40,
'same_col':0.30}
# -----------------------------------------------------------------------------
# Now add all field dictionaries into a list according to how they should be
# saved in the output file.
field_list = [givenname_dict, surname_dict, streetnumber_dict, address1_dict,
address2_dict, suburb_dict, postcode_dict, state_dict,
dob_dict, age_dict, phonenum_dict, ssid_dict, blocking_dict]
# -----------------------------------------------------------------------------
# Flag for writing a header line (keys 'name' of field dictionaries).
save_header = True # Set to 'False' if no header should be written
# -----------------------------------------------------------------------------
# String to be inserted for missing values.
missing_value = ''
# =============================================================================
# Nothing to be changed below here
# =============================================================================
# Initialise random number generator - - - - - - - - - - - - - - - - - - - - -
#
random.seed()
# =============================================================================
# Functions used by the main program come here
def error_position(input_string, len_offset):
"""A function that randomly calculates an error position within the given
input string and returns the position as integer number 0 or larger.
The argument 'len_offset' can be set to an integer (e.g. -1, 0, or 1) and
will give an offset relative to the string length of the maximal error
position that can be returned.
Errors do not likely appear at the beginning of a word, so a gauss random
distribution is used with the mean being one position behind half the
string length (and standard deviation 1.0)
"""
str_len = len(input_string)
max_return_pos = str_len - 1 + len_offset # Maximal position to be returned
if (str_len == 0):
return None # Empty input string
mid_pos = (str_len + len_offset) / 2 + 1
random_pos = random.gauss(float(mid_pos), 1.0)
random_pos = max(0,int(round(random_pos))) # Make it integer and 0 or larger
return min(random_pos, max_return_pos)
# -----------------------------------------------------------------------------
def error_character(input_char, char_range):
"""A function which returns a character created randomly. It uses row and
column keyboard dictionaires.
"""
# Keyboard substitutions gives two dictionaries with the neigbouring keys for
# all letters both for rows and columns (based on ideas implemented by
# Mauricio A. Hernandez in his dbgen).
#
rows = {'a':'s', 'b':'vn', 'c':'xv', 'd':'sf', 'e':'wr', 'f':'dg', 'g':'fh',
'h':'gj', 'i':'uo', 'j':'hk', 'k':'jl', 'l':'k', 'm':'n', 'n':'bm',
'o':'ip', 'p':'o', 'q':'w', 'r':'et', 's':'ad', 't':'ry', 'u':'yi',
'v':'cb', 'w':'qe', 'x':'zc', 'y':'tu', 'z':'x',
'1':'2', '2':'13', '3':'24', '4':'35', '5':'46', '6':'57', '7':'68',
'8':'79', '9':'80', '0':'9'}
cols = {'a':'qzw','b':'gh', 'c':'df', 'd':'erc','e':'d', 'f':'rvc','g':'tbv',
'h':'ybn','i':'k', 'j':'umn','k':'im', 'l':'o', 'm':'jk', 'n':'hj',
'o':'l', 'p':'p', 'q':'a', 'r':'f', 's':'wxz','t':'gf', 'u':'j',
'v':'fg', 'w':'s', 'x':'sd', 'y':'h', 'z':'as'}
rand_num = random.random() # Create a random number between 0 and 1
if (char_range == 'digit'):
# A randomly chosen neigbouring key in the same keyboard row
#
if (input_char.isdigit()) and (rand_num <= single_typo_prob['same_row']):
output_char = random.choice(rows[input_char])
else:
choice_str = string.replace(string.digits, input_char, '')
output_char = random.choice(choice_str) # A randomly choosen digit
elif (char_range == 'alpha'):
# A randomly chosen neigbouring key in the same keyboard row
#
if (input_char.isalpha()) and (rand_num <= single_typo_prob['same_row']):
output_char = random.choice(rows[input_char])
# A randomly chosen neigbouring key in the same keyboard column
#
elif (input_char.isalpha()) and \
(rand_num <= (single_typo_prob['same_row'] + \
single_typo_prob['same_col'])):
output_char = random.choice(cols[input_char])
else:
choice_str = string.replace(string.lowercase, input_char, '')
output_char = random.choice(choice_str) # A randomly choosen letter
else: # Both letters and digits possible
# A randomly chosen neigbouring key in the same keyboard row
#
if (rand_num <= single_typo_prob['same_row']):
if (input_char in rows):
output_char = random.choice(rows[input_char])
else:
choice_str = string.replace(string.lowercase+string.digits, \
input_char, '')
output_char = random.choice(choice_str) # A randomly choosen character
# A randomly chosen neigbouring key in the same keyboard column
#
elif (rand_num <= (single_typo_prob['same_row'] + \
single_typo_prob['same_col'])):
if (input_char in cols):
output_char = random.choice(cols[input_char])
else:
choice_str = string.replace(string.lowercase+string.digits, \
input_char, '')
output_char = random.choice(choice_str) # A randomly choosen character
else:
choice_str = string.replace(string.lowercase+string.digits, \
input_char, '')
output_char = random.choice(choice_str) # A randomly choosen character
return output_char
# -----------------------------------------------------------------------------
# Some simple funcions used for date conversions follow
# (based on functions from the 'normalDate.py' module by Jeff Bauer, see:
# http://starship.python.net/crew/jbauer/normalDate/)
days_in_month = [[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], \
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]]
def first_day_of_year(year):
"""Calculate the day number (relative to 1 january 1900) of the first day in
the given year.
"""
if (year == 0):
print 'Error: A year value of 0 is not possible'
raise Exception
elif (year < 0):
first_day = (year * 365) + int((year - 1) / 4) - 693596
else: # Positive year
leap_adj = int ((year + 3) / 4)
if (year > 1600):
leap_adj = leap_adj - int((year + 99 - 1600) / 100) + \
int((year + 399 - 1600) / 400)
first_day = year * 365 + leap_adj - 693963
if (year > 1582):
first_day -= 10
return first_day
# -----------------------------------------------------------------------------
def is_leap_year(year):
"""Determine if the given year is a leap year. Returns 0 (no) or 1 (yes).
"""
if (year < 1600):
if ((year % 4) != 0):
return 0
else:
return 1
elif ((year % 4) != 0):
return 0
elif ((year % 100) != 0):
return 1
elif ((year % 400) != 0):
return 0
else:
return 1
# -----------------------------------------------------------------------------
def epoch_to_date(daynum):
"""Convert an epoch day number into a date [day, month, year], with
day, month and year being strings of length 2, 2, and 4, respectively.
(based on a function from the 'normalDate.py' module by Jeff Bauer, see:
http://starship.python.net/crew/jbauer/normalDate/)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?