-
Notifications
You must be signed in to change notification settings - Fork 70
/
BEWGor.py
executable file
·2544 lines (1895 loc) · 114 KB
/
BEWGor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#usr/bin/python
#
# .`
# /
# :.
# `o
# +.
# .s
# y.
# ++
# -h`
# `d-
# h+
# ss
# sh`
# sh`
# `yh`
# .hy`
# /mo`
# .sd:
# `/dy.
# :hd:
# -ym+`
# -yms.
# .smy-
# `omh- ``````
# /md/ ```.-:-.
# .yNo` .-/:`
# /md- -+/
# oNy` /s`
# sMs` :y`
# +My y+
# -Nm` :d
# yM+ /d
# `NM` d+
# `MM od`
# mM. `sd.
# sMs ```````` `/ds`
# `dM/ ``-+shhmmmmmdhyso/-```````.:ohy-
# .mN+` `./shmmddhysssyyys/:/ohmdhyyyhhs/`
# `yNh:` `./sdmy+-oyyy/.```-oyyy- `yyy..`
# -yNds/.````.-/oydNmdh: .yyy: `yh/ syyo oyy.
# ./sdmmmmmmmhs+-`+yy: .yyy/`+ds: `syyo oyy.
# ```` -yyo /yyshy.`.:syys. .yys
# +yy+ :ymhyyyyyyy+` .syy-
# +yyo..ho.:/+++/-` :yyy-
# -syym+` `./syy+`
# -dyyyyso+//++oyyys/.
# `+hm: `-/+ossssso/:.
# :sd+`
# .
# ____ ______ __ __ _____
# | _ \ | ____| \ \ / / / ____|
# | |_) | | |__ \ \ /\ / / | | __ ___ _ __
# | _ < | __| \ \/ \/ / | | |_ | / _ \ | '__|
# | |_) | | |____ \ /\ / | |__| | | (_) | | |
# |____/ |______| \/ \/ \_____| \___/ |_|
#
#
# ___ _ _ _ ___
# | _ ) _ _ | | | | ( ) ___ | __| _ _ ___
# | _ \ | || | | | | | |/ (_-< | _| | || | / -_)
# |___/ \_,_| |_| |_| /__/ |___| \_, | \___|
# __ __ _ _ _ |__/ _
# \ \ / / ___ _ _ __| | | | (_) ___ | |_
# \ \/\/ / / _ \ | '_| / _` | | | | | (_-< | _|
# \_/\_/ \___/ |_| \__,_| |_| |_| /__/ \__|
# / __| ___ _ _ ___ _ _ __ _ | |_ ___ _ _
# | (_ | / -_) | ' \ / -_) | '_| / _` | | _| / _ \ | '_|
# \___| \___| |_||_| \___| |_| \__,_| \__| \___/ |_|
#
#
#
# Bull's Eye Wordlist Generator
# BEWGor (pronounced Booger)
#
# Inspired by and based on
# CUPP 3.1.0-alpha
# Common User Passnumbers Profiler
# Located at *** https://github.com/Mebus/cupp ***
#
# [Author]
#
# berzerk0 @ GitHub with Major Thanks to...
#
# Muris Kurgas aka j0rgan
# j0rgan [at] remote-exploit [dot] org
# http://www.remote-exploit.org
# http://www.azuzi.me
#
# ADDITIONAL THANKS TO:
#
# Willem Rebergen
# Michael Omari
# Kenth Kvein and Marcus Nordli
# Ramon Luis Ayala Rodriguez
# Lee McCormick
# Amelia and the rest of the Jax Crew
# Dominic 'TB' Peroso
# and Nick McGurk
#
#
# [DISCLAIMER]
#
# Any and all actions taken with this software are for LAWFUL, ETHICAL AND EDUCATIONAL PURPOSES ONLY.
# By using this software, you agree to not hold either berzerk0, GitHub or Muris Kurgas
# responsible for your actions.
# By using this you agree to these terms and are completely culpable for your own behavior.
#
#
# [LICENSE]
# This software is licensed under the GNU General Public License Version 3
#
# The Full Text of this license can be found at *** https://www.gnu.org/licenses/gpl-3.0.en.html ***
# A summarized, bullet point list of the license is presented below
# PERMISSIONS
# Commercial use
# Modification
# Distribution
# Patent use
# Private use
# CONDITIONS
# License and copyright notice
# State changes
# Disclose source
# Same license
# LIMITATIONS
# Liability
# Warranty
#------------------------Beginning of Actual Code------------------------#
#-----------Class, Function and Regex Definitions----------#
#import necessary libraries
import re, sys, time #re for regular expression use, sys for argument passing, time for determining when an event occured
from datetime import datetime # datetime in order to determine when an event occurred
from math import factorial #used to calculate permutation length
#----------Regular expressions to be used later to check for valid inputs---------#
four_digs_reg = re.compile("^[0-9]{4}$") #exactly 4 digits, no spaces
eight_digs_reg = re.compile("^[0-9]{8}$") #exactly 8 digits, no spaces
at_least_one_dig_reg = re.compile("^[0-9]+$") #at least one number, nothing else
nonzero_blankspace_reg = re.compile("^\s+$") #all empty spaces
letters_and_spaces_reg = re.compile('^[a-zA-Z \-]+$') #ensures a line only contains letters and spaces, supports hyphens (for names)
location_chars_reg = re.compile('[a-zA-Z\'\. ]') #matches only characters I predict would be found in a location's name
male_reg = re.compile('\s*[Mm][Aa][Ll][Ee]\s*') #matches all variations of the word 'male'
female_reg = re.compile('\s*[Ff][Ee][Mm][Aa][Ll][Ee]\s*') #matches all variations of the word 'female'
ends_in_space_reg = re.compile('\s+$') #matches strings with a space at the end - used to trim off this sapce
space_of_space_reg = re.compile('\s+[Oo]f\s+') #matches strings containing ' of ' or ' Of ' - a unique TitleCase rule
filename_reg = re.compile('^[a-zA-Z0-9\-_]+$') #forces a friendly filename
#Calculates number of permutations
def nPr(n, r):
#Implements the mathematical formula for permutations
if n-r > 0:
return factorial(n)/factorial(n-r)
else: return 1
# nPr = (n!)/(n-r)!
#Creates all possible permutations of a given list
#limits output creating length boundaries
# Write these outputs to a filename passed along
def bounded_permutations(iterable, min_length, max_length, outfile_name, r=None):
#This function is a modified version of the function from the Itertools library
#Check the itertools documentation for standard comments
#Comments included here are specific to BEWGor's modifications
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n: return
indices = range(n)
cycles = range(n, n-r, -1)
#Measures the string length of the created permutation - and only passes it along if it fits within boundaries
if min_length <= len(str(''.join((tuple(pool[i] for i in indices[:r]))))) <= max_length:
#writes permutation to file if it meets criteria
outfile.writelines((str(''.join(tuple(pool[i] for i in indices[:r])))) + '\n')
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
#Measures the string length of the created permutation - and only passes it along if it fits within boundaries
if min_length <= len(str(''.join((tuple(pool[i] for i in indices[:r]))))) <= max_length:
#writes permutation to file if it meets criteria
outfile.writelines((str(''.join(tuple(pool[i] for i in indices[:r])))) + '\n')
break
else: return
#shows the BEWGor logo in ASCII art
def showNose():
print ("""
.`
:
-.
`+
+.
-+
`s
`s.
s:
`s/
`s/
-y:
`+y.
:y+`
-ss.
-ss-
.sy: ```
`+h/` ```.-.`
-hs. .-:`
:d/ `/-
/m: o-
.m+ .s
sd .y
ds s:
dy `oo
+m. ``.::::-.`` `/s:
yd. `-+shddhhhhhsooso+//+oo:`
+do.` ``:oyyo:yys-..-oys` -hy-.`
.+hyo+++osyyohh. -yy-`yh .yy: `yy
`-:::-. +y/ `syoy:.-oys` -ys
`sy: `yyyyyys/` -yy.
`oy+y- `..` .+yo.
`ssyyo+//+osy+-
`sd+ .-://:-.
`- """)
#prints a fixed-width divider made of '---'
def divider():
print('---------------------------------------------------------------')
# Pause, press enter to coninue
def hold_up():
#This variable is never used, it is just a pause placeholder
#It does not persist after unpausing
holdup = raw_input('Press enter to continue...')
def isYearFuture(year):
date_format = "%Y" #sets 'YYYY" format
now = time.strftime(date_format) #current year in YYYY
# create datetime objects from the strings
year_val = datetime.strptime(year, date_format) # generate value for given year
now_val = datetime.strptime(now, date_format) # generate value for present year
if now_val < year_val: #if given year is in the future
return True #year is in the future
else:
return False #year is in past or present
# Function that checks if a date 'DDMMYYYY' is in the future
def isFullDateFuture(event_date):
#This function is only equipped to handle strings of exactly 8 digits.
#It assumes your
date_format = "%d%m%Y" #sets 'DDMMYYYY" format
now_date = time.strftime(date_format) #current date in DDMMYYYY
# create datetime objects from the strings
event_val = datetime.strptime(event_date, date_format) # generate value for given date
now_val = datetime.strptime(now_date, date_format) # generate value for present date
if now_val < event_val: #if given date is in the future
return True #event is in the future
else:
return False #event is in past or present
#Function to check if day 'DDMM' exists
def doesDayExist(day):
#if a passed string of 4 digits is on the list of nonexistent days,
#this function returns false.
#If a date is created that claims to be on the 32nd+ day of a month
# This is caught elsewhere, before this function is called
unreal_days = ['3002','3102','3104','3106','3109','3111']
# 30 and 31 Feb
# 31 April
# 31 June
# 31 September
# 31 November
#These days do not exist, and should not be allowed
if day in unreal_days: return False # if one of the non-existant days
else: return True
#Function to check if given day is valid leap day
def isItInvalidLeap(full_date):
# This will return false for any day that isn't 29 Feb, or 29 Feb of a leap year
# It will only return true for 29 Feb for a Non-Leap year
if full_date[0:4] == '2902': # if 29 February
if (int(full_date[4:8]) - 2016) % 4 == 0: # checks to see if given year has Leap Day
# 2016 was a leap year, and any year that is separate from 2016 by a multple of 4
# is also a leap year
return False #if not a leap year
else: return True #if a date is 29 Feb of a non-leap year
else: return False #if not 29 Feb
# Generates Chinese Zodiac sign for a given year
# This function is not integrated into a class because it can
# also be used on a list of arbitrary years
def getChineseZodiac(birth_year):
birthyear =int(birth_year) #converts from string so modulo can be used
#The Chinese Zodiac has 12 Signs, and therefore repeats every 12 years.
#If a given year is separated by one of the landmark years given below by a multiple of 12, the signs for those two years are equal
# 2017 and 2002 are both years of the rooster. 2017 and 1897 are both years of the rooster
if ((birthyear - 2008) % 12) == 0: chinese_zodiac = "rat"
elif ((birthyear - 2009) % 12) == 0: chinese_zodiac = "ox"
elif ((birthyear - 2010) % 12) == 0: chinese_zodiac = "tiger"
elif ((birthyear - 2011) % 12) == 0: chinese_zodiac = "rabbit"
elif ((birthyear - 2012) % 12) == 0: chinese_zodiac = "dragon"
elif ((birthyear - 2013) % 12) == 0: chinese_zodiac = "snake"
elif ((birthyear - 2014) % 12) == 0: chinese_zodiac = "horse"
elif ((birthyear - 2015) % 12) == 0: chinese_zodiac = "goat"
elif ((birthyear - 2016) % 12) == 0: chinese_zodiac = "monkey"
elif ((birthyear - 2017) % 12) == 0: chinese_zodiac = "rooster"
elif ((birthyear - 2018) % 12) == 0: chinese_zodiac = "dog"
else: chinese_zodiac = "pig"
# Some signs can have multiple names, so BEWGor will prompt the user for their choice
# Years of the Rat may also be called Years of the Mouse, as there may be no easy distinction between the two in Chinese
if chinese_zodiac == "rat":
print ("\n The Chinese Zodiac sign for the year " + birth_year +" is the '" + chinese_zodiac.title() +"'")
print (" This sign is usually called the Rat, but occaisionally it is called the Mouse.")
print (' Which would you like to use? 1 - Rat, 2 - Mouse, 3 - Both') # user chooses which value
zodiac_choice = raw_input("> Enter the number of your choice here >:")
#If user inputs a choice not on the list of provided choices, the process repeats until they do.
while zodiac_choice !=str(1) and zodiac_choice !=str(2) and zodiac_choice !=str(3): #Checks for valid choice
print (" [-] Invalid choice, try again.")
print (" This sign is usually called the Rat, but occaisionally it is called the Mouse.")
print (' Which would you like to use? 1 - Rat, 2 - Mouse, 3 - Both') #user chooses which value
if zodiac_choice == str(1):chinese_zodiac = "rat"
if zodiac_choice == str(2):chinese_zodiac = "mouse"
if zodiac_choice == str(3):chinese_zodiac = "mouse rat"
# Years of the Goat may also be called Years of the Sheep or Ram - there is less distinction between these animals in Chinese
elif chinese_zodiac == "goat":
print ("\n The Chinese Zodiac sign for the year " + birth_year +" is the '" + chinese_zodiac.title() +"'")
print (" This sign is often called the Ram or Sheep as well as the Goat.")
print (" Which would you like to use? 1 - Goat, 2 - Ram, 3 - Sheep, 4 - All Three") #user chooses which value
zodiac_choice = raw_input("> Enter the number of your choice here >:")
#If user inputs a choice not on the list of provided choices, the process repeats until they do.
while zodiac_choice !=str(1) and zodiac_choice !=str(2) and zodiac_choice !=str(3) and zodiac_choice != str(4): #Checks for valid choice
print (" [-] Invalid choice, try again.")
print (" This sign is often called the Ram or Sheep as well as the Goat.")
print (" Which would you like to use? 1 - Goat, 2 - Ram, 3 - Sheep, 4 - All Three") #user chooses which value
zodiac_choice = raw_input("> Enter the number of your choice here >:")
if zodiac_choice == str(1): chinese_zodiac = "goat"
if zodiac_choice == str(2): chinese_zodiac = "ram"
if zodiac_choice == str(3): chinese_zodiac = "sheep"
if zodiac_choice == str(4): chinese_zodiac = "goat ram sheep"
# Years of the Pig may be called years of the Boar, but this translation is rare
elif chinese_zodiac == "pig":
print ("\n The Chinese Zodiac sign for the year " + birth_year +" is the '" + chinese_zodiac.title() +"'")
print (" This sign is usually called the Pig, but rarely it is called the Boar.") #user chooses which value
print (' Which would you like to use? 1 - Pig, 2 - Boar, 3 - Both ') #user chooses which value
zodiac_choice = raw_input("> Enter the number of your choice here >:")
#If user inputs a choice not on the list of provided choices, the process repeats until they do.
while zodiac_choice !=str(1) and zodiac_choice !=str(2) and zodiac_choice !=str(3): #Checks for valid choice
print (" [-] Invalid choice, try again.")
print (" This sign is usually called the Pig, but rarely it is called the Boar.")
print (' Which would you like to use? 1 - Pig, 2 - Boar, 3 - Both ') #user chooses which value
zodiac_choice = raw_input("> Enter the number of your choice here >:")
if zodiac_choice == str(1):chinese_zodiac = "pig"
if zodiac_choice == str(2):chinese_zodiac = "boar"
if zodiac_choice == str(3):chinese_zodiac = "pig boar"
return chinese_zodiac
#Function that takes a string that contains spaces and creates variations
# also handles TitleCase variants of phrases containing the world 'of'
def spaceHandler(phrase):
if ' ' in phrase: #if a phrase contains spaces, split it up so BEWGor can join the words together with variations
phrase = phrase.title() #make first letter of every word capital, including "Of"
#This changes the user's input, but later on in the script, varitaions will be created, such as all upper or lowercase
in_phrases = [phrase] #put the phrase on to a list that will be expanded and iterated over if a phrase contains 'Of'
out_phrases = [] #list that will hold generated variations
#This block addresses possibile capitalization of the word 'of'
# In TitleCase, 'of' does not conventially have a capital 'O'
# However, this is not always done consistently.
# BEWGor creates variations where of is and isn't in TitleCase
if len(space_of_space_reg.findall(phrase)) > 0: in_phrases.append(phrase.replace(' Of ', ' of ')) #if ' Of ' in string, created variations
for item in in_phrases: # for all variations
space_breakup = item.split(' ') #breakup by space
#Rejoin by other phrases
out_phrases.append('_'.join(space_breakup)) #creates variation joined by underscores - 'Some_Words'
out_phrases.append('-'.join(space_breakup)) #creates variation joined by dashes - 'Some-Words'
out_phrases.append(''.join(space_breakup)) #creates variation joined directly - 'SomeWords'
out_phrases.extend(space_breakup) #adds indivudual words to the list indepedently, 'Some' and 'Words'
return list(set(out_phrases)) #returns all variations and words extracted, after removing duplicates
else: return phrase #if phrase did not have a space, return phrase as is
#Function that takes spaces off the end of a string
def spaceShaver(phrase):
while len(ends_in_space_reg.findall(phrase)) > 0: #if the name ends in spaces...
phrase = phrase[0:-1] #keep removing characters from the string until it doesn't end in a space
return phrase
# This feature will be expanded upon after Initial release
# The plan is to generate a specially formatted file that can be
# created to and then fed into this program directly instead of going prompt by prompt
# ALPHA RELEASE FUNCTION - outputs all entered values to a file.
def outputTerms(term_list):
print("""\n ---------- Output 'Terms' to a File --------
All values have been entered, BEWGor can save them directly to a txt file.""")
term_write_choice = raw_input('> Would you like to do this? (Y/N) >:').upper() #prompts user for choice
term_write_choice = spaceShaver(term_write_choice)
if term_write_choice in "YES" and len(term_write_choice) != 0:
print(' If you do not enter a filename, the default will be "BEWGor_Terms.txt')
outfile_name = raw_input('> Enter a filename, without the ".txt" extension >:')
# If the inputted filename is non-zero in length, but contains unfriendly characters
# Sometimes filenames containing characters like spaces () " ' {} can cause problems
# The regex forces the filename to exculde these characters
while len(outfile_name) !=0 and not filename_reg.match(outfile_name):
print(' [-] Invalid filename, try again.')
outfile_name = raw_input("> Enter a filename, without the .txt extension >:")
if len(outfile_name) ==0 : outfile_name = 'BEWGor_Terms'
outfile = open(outfile_name+'.txt','w+') #opens file to be written
outfile.truncate() # ensures file is empty
term_list.sort(key=len) # sort by length
term_list = list(set(term_list)) #removes duplicates
for item in term_list: #write every line to file
outfile.writelines(item + '\n') #write to file
divider()
#announces that the Terms file has been written and its length
print('\n ' + str(len(term_list)) + ' terms written to ' + outfile_name + '.txt')
#General class for the people mentioned in the prompt
#Parent class of MAINSUBJECT
class Person(object): #This class allows us to easily add and store information for an aribitrary number of people
#Initialize Person Class and variables
def __init__(self,name,maiden_name,initials,nicknames,birth_day,birth_year,greek_zodiac,chinese_zodiac,Birthstone):
self.name=name
self.maiden_name = maiden_name
self.initials = initials
self.nicknames = nicknames
self.birth_day = birth_day
self.birth_year=birth_year
self.greek_zodiac = greek_zodiac
self.chinese_zodiac = chinese_zodiac
self.Birthstone = Birthstone
#Person Class Function that requests Person's Name
def getName(self):
self.initials = '' #defined as empty, in case name is not generated -> this would confused the program later on
person_name = raw_input("> Enter " + self.name + "'s Full Name, separated by spaces - or as much as you have >:").title()
if len(person_name) == 0: valid = True
else: valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
#If the user enters a value, it must meet criteria
# until all criteria is met, or a Null value is entered, BEWGor will keep asking
while len(person_name) !=0 and not valid:
# the 'valid' boolean keeps us from getting stuck in an infinite loop here if the user decides to enter an empty field after
# being told their first input was invalid
if nonzero_blankspace_reg.match(person_name): #ensures input isn't only blank space characters
valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
print (" [-] Empty Space, try again.")
person_name = raw_input("> Enter " + self.name + "'s Full Name, separated by spaces - or as much as you have >:").title()
elif not letters_and_spaces_reg.match(person_name):
valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
print (" [-] Input contains non-letter characters, try again.")
person_name = raw_input("> Enter " + self.name + "'s Full Name, separated by spaces - or as much as you have >:").title()
else: valid = True #if the name input is valid, continue
person_name = spaceShaver(person_name) # removes spaces from end of name
if len(person_name) != 0: #if name is entered, BEWGor sets the person's name to the entry.
#If name is NOT entered, then BEWGor uses the temporary value passed in construction of the Person instance.
self.name = person_name #set class variable to input value
# if name is given, this block extracts the person's Initials.
initials = ""
for i in self.name.title(): #set first letter of each part of name to be capital
if i.isupper(): initials += i #if letter is capital, add to initials string
self.initials = initials.upper() #ensure that initials are upper and add to instance variables
#Class Function that requests Person's Maiden Name
def getMaidenName(self):
person_maiden_name = raw_input("> Enter " + self.name +"'s Maiden Name - if applicable >:").title()
# The 'valid' boolean is true if the name value is empty or meets the correct criteria
if len(person_maiden_name) == 0: valid = True
else: valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
#If the user enters a value, it must meet criteria
# until all criteria is met, or a Null value is entered, BEWGor will keep asking
while len(person_maiden_name) !=0 and not valid:
# the 'valid' boolean keeps us from getting stuck in an infinite loop here if the user decides to enter an empty field after
# being told their first input was invalid
if nonzero_blankspace_reg.match(person_maiden_name): #ensures input isn't only blank space characters
valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
print (" [-] Empty Space, try again.")
person_maiden_name = raw_input("> Enter " + self.name +"'s Maiden Name, separated by spaces - if applicable >:").title()
elif not letters_and_spaces_reg.match(person_maiden_name): #checks to see if value contains improper characters
valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
print (" [-] Input contains non-letter characters, try again.")
person_maiden_name = raw_input("> Enter " + self.name + "'s Maiden Name, separated by spaces - if applicable >:").title()
else: valid = True
self.maiden_name = spaceShaver(person_maiden_name) #remove spaces from end of name
# Person Class Function that requests Nicknames
def getNicknames(self):
print (""" For nicknames, think about common name shortenings,
such as 'Michael' into 'Mike'
Also enter usernames and online handles.
""")
nicknames =[] #list that will contain inputted nicknames, or return blank if none are given
entered = []
nickname = raw_input("> Enter one of " + self.name + "'s Nicknames or usernames, or simply press enter to move on >:")
#If the user enters a value, it must meet criteria
# until all criteria is met, or a Null value is entered, BEWGor will keep asking
while len(nickname) != 0: #if no nicknames added, move on.
if nonzero_blankspace_reg.match(nickname): #ensures input isn't only blank space characters
nickname = raw_input("> Enter one of " + self.name + "'s Nicknames or usernames, or simply press enter to move on >:")
elif nickname in nicknames or nickname in entered: #check for double input
print (" [-] That input has already been entered. Try again >:")
nickname = raw_input("> Enter one of " + self.name + "'s Nicknames or usernames, or simply press enter to move on >:")
elif ' ' in nickname:
nicknames.extend((spaceHandler(nickname))) #create variants of input if input contains spaces
entered.append(nickname) #adds to 'entered' list to prevent double-adds
else:
nicknames.append(nickname) #adds input to list if valid
entered.append(nickname) # adds to 'entered" list to prevent double-adds
nickname = raw_input("> Enter one of " + self.name + "'s Nicknames or usernames, or simply press enter to move on >:")
nicknames=list(set(nicknames)) #remove duplicates
self.nicknames = ' '.join(nicknames)
#Person Class Function that requests Birth day (no year)
def getBirthday(self):
print(' Be Aware BEWGor uses DDMM formatting!\n Winter Solstice falls on 21/12, 22/12, or 23/12 in this format.')
person_birth_day = raw_input("> Enter " + self.name +"'s Birthday (without year, DDMM) >:")
valid = False # without this boolean, we might get stuck in a logical loop if the user enters an invalid input followed by an empty one
#If the user enters a value, it must meet criteria
# until all criteria is met, or a Null value is entered, BEWGor will keep asking
while len(person_birth_day) !=0 and not valid:
# the 'valid' boolean keeps us from getting stuck in an infinite loop here if the user decides to enter an empty field after
# being told their first input was invalid
if not four_digs_reg.match(person_birth_day): #ensures input is four digits exactly, nothing else
print (" [-] Days must be exactly 4 digits")
person_birth_day = raw_input("> Enter " + self.name +"'s Birthday (without year, DDMM) >:")
elif int(person_birth_day[2:4]) > 12: #checks for an invalid month
print (" [-] Invalid month- After December, but before January - check your DDMM format")
person_birth_day = raw_input("> Enter " + self.name +"'s Birthday (without year, DDMM) >:")
elif int(person_birth_day[0:2]) > 31: #checks for an invalid day
print (" [-] Invalid Day, no month has more than 31 days. Try again.")
person_birth_day = raw_input("> Enter " + self.name +"'s Birthday (without year, DDMM) >:")
elif not doesDayExist(person_birth_day): #ensures day exists
print (" [-] Invalid date. That month has fewer days. Try again.")
valid = False
person_birth_day = raw_input("> Enter " + self.name +"'s Birthday (without year, DDMM) >:")
else: valid = True #all criteria have been met
self.birth_day = person_birth_day #change value to entry - including to a null value if nothing is entered
#Person Class Function that requests birth YEAR
def getBirthyear(self):
person_birth_year = raw_input("> Enter " + self.name +"'s Birth year (YYYY) >:")
valid = False
#If the user enters a value, it must meet criteria
# until all criteria is met, or a Null value is entered, BEWGor will keep asking
while len(person_birth_year) !=0 and not valid:
if not four_digs_reg.match(person_birth_year): #ensures input is four digits exactly, nothing else
print (" [-] Birth years must be exactly 4 digits, try again.")
person_birth_year = raw_input("> Enter " + self.name +"'s Birth year (YYYY) >:")
elif isYearFuture(person_birth_year): #ensures user does not enter a year in the future
print (" [-] That year is in the future, try again.")
person_birth_year = raw_input("> Enter " + self.name +"'s Birth year (YYYY) >:")
else: valid = True #if all criteria have been met
self.birth_year = person_birth_year #change value to entry - including to a null value if nothing is entered
#Person Class Function that determines Greek Zodiac Sign (Mythological/Traditional) from birthday
def getGreekZodiac(self):
greek_zodiac = '' #sets a null value, so if user doesn't want to include this value, BEWGor can pass an empty value
incl_Greek_Zod = raw_input("Would you like to include " + self.name + "'s Greek Zodiac Sign? (Y/N) >:").upper() #only determines/includes Greek Zodiac sign if user allows it
incl_Greek_Zod = spaceShaver(incl_Greek_Zod) # cleans up input and stops false negative with "yes "
if incl_Greek_Zod in "YES" and len(incl_Greek_Zod) != 0: #if user enters 'yesno,' they think they are slick and BEWGor will treat their input as a 'yes'
# Greek Zodiac Signs:
#Aquarius: 20 January (01) - 18 February (02)
#Pisces: 19 February (02) - 20 March (03)
#Aries: 21 March (03) - 19 April (04)
#Taurus: 20 April (04) - 20 May (05)
#Gemini: 21 May (05) - 20 June (06)
#Cancer: 21 June (06) - 22 July (07)
#Leo: 23 July (07) - 22 August (08)
#Virgo: 23 August (08) - 22 September (09)
#Libra: 23 September (09) - 22 October (10)
#Scorpio: 23 October (10) - 21 November (11)
#Sagittarius: 22 November (11) - 21 December (12)
#Capricorn: 22 December (12) - 19 January (01)
birthmonth = self.birth_day[2:4] #isolate the month from the birthday
birth_day = int(self.birth_day[0:2]) # isolate the day from the birthday, convert to int for comparison
# Corresponding dates for January
if birthmonth == ('01'):
if birth_day <= 19: greek_zodiac = 'capricorn'
else: greek_zodiac = 'aquarius'
# Corresponding dates for February
elif birthmonth == ('02'):
if birth_day <= 18: greek_zodiac = 'aquarius'
else: greek_zodiac = 'pisces'
# Corresponding dates for March
elif birthmonth == ('03'):
if birth_day <= 20: greek_zodiac = 'pisces'
else: greek_zodiac = 'aries'
# Corresponding dates for April
elif birthmonth == ('04'):
if birth_day <= 19: greek_zodiac = 'aries'
else: greek_zodiac = 'taurus'
# Corresponding dates for May
elif birthmonth == ('05'):
if birth_day <= 20: greek_zodiac = 'taurus'
else: greek_zodiac = 'gemini'
# Corresponding dates for June
elif birthmonth == ('06'):
if birth_day <= 20: greek_zodiac = 'gemini'
else: greek_zodiac = 'cancer'
# Corresponding dates for July
elif birthmonth == ('07'):
if birth_day <= 22: greek_zodiac = 'cancer'
else: greek_zodiac = 'leo'
# Corresponding dates for August
elif birthmonth == ('08'):
if birth_day <= 22: greek_zodiac = 'leo'
else: greek_zodiac = 'virgo'
# Corresponding dates for September
elif birthmonth == ('09'):
if birth_day <= 22: greek_zodiac = 'virgo'
else: greek_zodiac = 'libra'
# Corresponding dates for October
elif birthmonth == ('10'):
if birth_day <= 22: greek_zodiac = 'libra'
else: greek_zodiac = 'scorpio'
# Corresponding dates for November
elif birthmonth == ('11'):
if birth_day <= 21: greek_zodiac = 'scorpio'
else: greek_zodiac = 'sagittarius'
# Corresponding dates for December
else:
if birth_day <= 21: greek_zodiac = 'sagittarius'
else: greek_zodiac = 'capricorn'
print ("\n [+] Recorded " + self.name + "'s Greek Zodiac sign as '" + greek_zodiac.title() +"' \n") #alert user to inclusion of Greek Zodiac
self.greek_zodiac = greek_zodiac #change value to entry - including to a null value if nothing is entered
#Person Class Function that determines Birthstone (Mythological/Traditional) from birth month
def getBirthstone(self):
# Birthstones are an old tradition in that (in the West) may be associated with the signs of the Zodiac.
# They are highly popular in some parts of the world, but nearly unheard of in others.
# If your Subject is into astrology or New Age belief, this could be of great importance to them
# It also might mean they are vulnerable to social engineering and cold reading often practiced by 'psychics'
Birthstone = '' #sets a null value, so if user doesn't want to include this value, BEWGor can pass an empty value
incl_Birthstone = raw_input("Would you like to include " + self.name + "'s Birthstone (Y/N) >:").upper() #only determines/includes Birthstone if user allows it
incl_Birthstone = spaceShaver(incl_Birthstone) # cleans up input and stops false negative with "yes "
if incl_Birthstone in "YES" and len(incl_Birthstone) != 0: #if user enters 'yesno,' they think they are slick and BEWGor will treat their input as a 'yes'#only take action if user requests it
#if user enters 'yesno,' they think they are slick and BEWGor will treat their input as a 'yes'
birthmonth = self.birth_day[2:4] #isolate birth month
print ("\n Is " + self.name + " more likely to use a Birthstone from a Western or Hindu list?") #there are multiple lists of Birthstones, two are included
stone_choice = raw_input("> Enter 1 for Western, 2 for Hindu, or 3 to use both >:")
#If user inputs a choice not on the list of provided choices, the process repeats until they do.
while stone_choice !=str(1) and stone_choice !=str(2) and stone_choice != str(3):
print (' [-] Invalid choice, try again.')
print (" Is " + self.name + " more likely to use a Birthstone from a Western or Hindu list?")
stone_choice = raw_input("> Enter 1 for Western, 2 for Hindu, or 3 to use both >:")
if stone_choice == str(1): #if user requests a Western list
western_dict = {'01' :'garnet', '02' :'amethyst', '03' :'aquamarine', '04' :'diamond', '05' :'emerald', '06' :'pearl', '07' :'ruby', '08' :'peridol', '09' :'sapphire', '10' :'opal', '11' :'topaz', '12' :'turquoise'}
Birthstone = str(western_dict.get(birthmonth)).lower()
elif stone_choice == str(2): #if user requests a Hindu list
hindu_dict = {'01' :'serpent-stone', '02' :'chandrakanta', '03' :'siva-linga', '04' :'diamond', '05' :'emerald', '06' :'pearl', '07' :'sapphire', '08' :'ruby', '09' :'zircon', '10' :'coral', '11' :'cats-eye', '12' :'topaz'}
Birthstone = str(hindu_dict.get(birthmonth)).lower()
elif stone_choice == str(3): #if user requests both lists
western_dict = {'01' :'garnet', '02' :'amethyst', '03' :'aquamarine', '04' :'diamond', '05' :'emerald', '06' :'pearl', '07' :'ruby', '08' :'peridol', '09' :'sapphire', '10' :'opal', '11' :'topaz', '12' :'turquoise'}
hindu_dict = {'01' :'serpent-stone', '02' :'chandrakanta', '03' :'siva-linga', '04' :'diamond', '05' :'emerald', '06' :'pearl', '07' :'sapphire', '08' :'ruby', '09' :'zircon', '10' :'coral', '11' :'cats-eye', '12' :'topaz'}
if western_dict.get(birthmonth) != hindu_dict.get(birthmonth): # include both dictionaries if stones aren't the same
Birthstone = (str(western_dict.get(birthmonth)).lower() + " " + (str(hindu_dict.get(birthmonth)).lower()))
else: Birthstone = str(western_dict.get(birthmonth)).lower() # if the stones are the same, use just one list
print ("\n [+] Recorded " + self.name + "'s Birthstone as '" + Birthstone.title() +"' \n") #alert user to inclusion of Birthstone word
self.Birthstone= Birthstone #change value to entry - including to a null value if nothing is entered
#Person Class function that determines Chinese Zodiac Sign (Mythological) from birth year
def getPersonChineseZodiac(self):
# This traditional Zodiac is still quite popular in parts of Asia.
# According to Wikipedia, it is based on an approximation of the 11.86 year oribit of the planet Jupiter
# The form BEWGor uses is derived from the Chinese variation, which is the most popular, especially in the West
# However, there are variations that have slight differences
# Vietnamese, Thai, and some Turkic peoples (Like Khazars) use variants of the Chinese Zodiac
# Check https://en.wikipedia.org/wiki/Chinese_zodiac#Chinese_zodiac_in_other_countries to see if your Subject may use a different list
# If that is the case, you may input their terms in the "Additional Words" prompt
self.chinese_zodiac = '' # sets a null value, so if user doesn't want to include this value, BEWGor can pass an empty value
if len (self.birth_year) == 4: # Chinese Zodiac sign can only be determined if a birth year is given
incl_Chinese_Zod = raw_input("Would you like to include " + self.name + "'s Chinese Zodiac Sign? (Y/N) >:").upper() #only determines/includes Chinese Zodiac sign if user allows it
incl_Chinese_Zod = spaceShaver(incl_Chinese_Zod) # cleans up input and stops false negative with "yes "
if incl_Chinese_Zod in "YES" and len(incl_Chinese_Zod) != 0: #if user enters 'yesno,' they think they are slick and BEWGor will treat their input as a 'yes'#if user enters 'yesno,' they think they are slick and BEWGor will treat their input as a 'yes'
self.chinese_zodiac = getChineseZodiac(self.birth_year)
print ("\n [+] Recorded " + self.name + "'s Chinese Zodiac sign as the '" + self.chinese_zodiac.title() +"'\n") #alert user to inclusion of Chinese Zodiac
#Person Class Function that requests info about given person
def inputInfo(self):
#Dividers are included to clean up the input process
#functions are called to collect information from the User
divider()
self.getName()
divider()
self.getMaidenName()
divider()
self.getNicknames()
divider()
self.getBirthday()
divider()
self.getBirthyear()
# The following block ensures the entered birthday is in the present or past - if the full date is known
valid = False # this boolean causes the while loop to run until a vaild birthdate is entered
while len(self.birth_day) != 0 and len(self.birth_year) !=0 and not valid:
full_birthday = self.birth_day + self.birth_year #creates a full birth date out of birthday and birthyear
if isItInvalidLeap(full_birthday): # if a given birth date takes place on leap day, it must be verified that date existed in the given year
print (" [-] That day did not take place that year. Try again. \n")
#if the given year did not have a leap day, the birthday must be verified
self.getBirthday()
divider()
self.getBirthyear()
divider()
#If a given birth date is in the future, the User has made an error.
# Either the inputted date is invalid, or the User as the ability to time travel and shouldn't have to bother using BEWGor.
elif isFullDateFuture(full_birthday):
print (" [-] You have selected a birthday in the future, that can't be right. \n")
# Verify birthday as in the past
self.getBirthday()
divider()
self.getBirthyear()
else: valid = True
#if valid birthday is present, acquire associated mythology - if the user wishes
if len(self.birth_day) != 0:
divider()
self.getGreekZodiac()
divider()
self.getBirthstone()
else:
self.greek_zodiac = ''
self.Birthstone = ''
if len(self.birth_year) != 0:
divider()
self.getPersonChineseZodiac()
else:
self.chinese_zodiac = ''
#Person Class Function that outputs important numbers
def outputWords(self):
word_output = [] #list that will be filled with output words
#This condition prevents default titles used in class Construction from being used in wordlist generation
# If the user knows a person exists, but cannot provide a specific name
#This condition prevents BEWGor from using 'Child_Number_1' on the wordlist
name_cond = 'Significant_Other' not in self.name and 'Child_Number_' not in self.name and 'Sibling_Number_' not in self.name and "Pet_Number_" not in self.name and "Parent_Number_" not in self.name
#Some of the length checks, particularly the lines that include "extend" may be redundant - but they are left in for robustness
#You know how coding is - 'That line doesn't seem to do anything, I'll delete it. Why doesn't it work anymore?'
if len(self.name) != 0 and name_cond : word_output.extend(((self.name).lower()).split(' ')) # add Person's Name, if valid, broken up by spaces
if len(self.initials) != 0 : word_output.append(self.initials) # add Person's initials, which have been generated automatically
if len(self.maiden_name) != 0: word_output.append((self.maiden_name).lower()) # add Person's maiden name, assumed to not have spaces
if len(self.nicknames) != 0: word_output.extend(((self.nicknames).lower()).split(' ')) # add person's nicknames, if present, broken up by spaces
if len(self.greek_zodiac) != 0: word_output.append((self.greek_zodiac).lower()) # add greek zodiac sign if present
if len(self.Birthstone) != 0: word_output.extend((self.Birthstone).lower().split(' ')) # add Birthstone(s) if present
if len(self.chinese_zodiac) != 0:word_output.extend((self.chinese_zodiac).lower().split(' ')) # add chinese zodiac if present
return word_output
#Person Class Function that outputs important Days
def outputDays(self):
#ALPHA RELEASE - the flat 'person' class only has one important day.
# future releases will have relationship specific days such as 'anniversary'
day_output = []
if len(self.birth_day) != 0: day_output.append(self.birth_day)
return day_output
#Person Class Function that outpus important Years
def outputYears(self):
#ALPHA RELEASE - the flat 'person' class only has one important year.
# future releases will have relationship specific years
year_output = []
if len(self.birth_year) != 0: year_output.append(self.birth_year)
return year_output
#Person class function that outputs important full dates
def outputFullDates(self):
#ALPHA RELEASE - the flat 'person' class only has one important full date
# future releases will have relationship specific full dates such as 'anniversary'
full_date_output=[]
full_birthday = self.birth_day + self.birth_year
if len(full_birthday) == 8: full_date_output.append(full_birthday) #if both birth_day and birth_year are present, add combination to list
return full_date_output
#Class with main-subject specific information
# Child class of PERSON
class MainSubject(Person):
def __init__(self,name,maiden_name,initials,nicknames,birth_day,birth_year,greek_zodiac,chinese_zodiac,Birthstone,gender,nationality,natl_demonym,natl_day,ethnicity,birthplace,hometown):
#Create Main Subject Variables
self.name = name
self.gender = gender
self.nationality = nationality
self.natl_demonym = natl_demonym
self.natl_day = natl_day
self.ethnicity = ethnicity
self.birthplace = birthplace
self.hometown = hometown
#ALPHA NOTE: to be included after alpha release
# self.local_demonym
# education
# career
# Favorite things
# and more
#Requests main subjects gender identity
def getGender(self):
print ("---" + self.name +"'s Gender Identity, in all relevant forms---")
print ("""
MALE and FEMALE are the most commonly identified genders.
BEWGor can include (English) synonyms for these two choices if
they are entered. You may wish to inlcude synonyms in the
Subject's native language. For example, a Spanish speaker might
include "chico" in their password. A German speaker may include "Frau"
Transgendered or transsexual people may identify as male,
female, trans, queer or something else. Some people do not identify with
the concept of a binary Male/Female gender system.
Note that sexuality is different than gender identity,
and that there will not be a prompt requesting information
about sexuality specifically. If you have information you
wish to include about your subject's sexuality do so in the
"ADDITIONAL WORDS" prompt at the end of the profiling process.
Use 'male' or 'female' to bring up a prompt to include synonyms.