├── .gitignore ├── README.md ├── notes.txt ├── LICENSE ├── code_snippets.py ├── test.py └── personality.py /.gitignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | *.geany 3 | *.pyc 4 | *.txt 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MBTI 2 | A program that generates a number of MBTI personality type objects in the correct percentage given the sample space based on the probabilities given in http://www.mypersonality.info/ 3 | 4 | ## Background and History 5 | This project started out as a way to practice programming using concepts in Statstics. I decided to use 'data' for the MBTI to make it more interesting. I might use this in possible future projects (e.g. games, simulations, etc.). 6 | 7 | ## License 8 | [MIT License](LICENSE) 9 | -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | A Person has a/an: 2 | Name 3 | (FirstName 4 | MiddleName 5 | Surname 6 | Nickname) 7 | (Gender) 8 | (Age) 9 | (DateOfBirth 10 | DayOfBirth 11 | MonthOfBirth 12 | YearOfBirth) 13 | 14 | Personality 15 | Extraversion/Introversion 16 | Sensing/Intuition 17 | Thinking/Feeling 18 | Judging/Perceiving 19 | CognitiveFunctions 20 | Dominant 21 | Auxiliary 22 | Tertiary 23 | Inferior 24 | (Temperament, Role, RoleVariant 25 | Concrete/Abstract 26 | Cooperative/Utilitarian 27 | Directive/Informative 28 | Expressive/Attentive) 29 | 30 | Personality 31 | Temperament 32 | PersonalityType 33 | CognitiveFunctions 34 | PreferencesStrengths 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Adei Josol 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /code_snippets.py: -------------------------------------------------------------------------------- 1 | _temperament_names = { 2 | 'SP': ['Artisan', 'Creator'], 3 | 'SJ': ['Guardian', 'Protector'], 4 | 'NF': ['Idealist', 'Visionary'], 5 | 'NT': ['Rational', 'Intellectual'] 6 | } 7 | 8 | _personality_type_names = { 9 | 'SP': { 10 | 'ESFP': ['Performer', 'Entertainer', 'Performer'], 11 | 'ESTP': ['Promoter', 'Persuader', 'Doer'], 12 | 'ISFP': ['Composer', 'Artist', 'Artist'], 13 | 'ISTP': ['Crafter', 'Craftsman', 'Mechanic'] 14 | }, 15 | 'SJ': { 16 | 'ESFJ': ['Provider', 'Supporter', 'Caregiver'], 17 | 'ESTJ': ['Supervisor', 'Overseer', 'Guardian'], 18 | 'ISFJ': ['Protector', 'Defender', 'Nurturer'], 19 | 'ISTJ': ['Inspector', 'Examiner', 'Duty Fulfiller'] 20 | }, 21 | 'NF': { 22 | 'ENFP': ['Champion', 'Advocate', 'Inspirer'], 23 | 'ENFJ': ['Teacher', 'Mentor', 'Giver'], 24 | 'INFP': ['Healer', 'Dreamer', 'Idealist'], 25 | 'INFJ': ['Counselor', 'Confidant', 'Protector'] 26 | }, 27 | 'NT': { 28 | 'ENTP': ['Inventor', 'Originator', 'Visionary'], 29 | 'ENTJ': ['Fieldmarshal', 'Chief', 'Executive'], 30 | 'INTP': ['Architect', 'Engineer', 'Thinker'], 31 | 'INTJ': ['Mastermind', 'Strategist', 'Scientist'] 32 | } 33 | } 34 | 35 | _preference_names = { 36 | 'E': ['Extraversion', 'Extravert', 'Extraverted'], 37 | 'I': ['Introversion', 'Introvert', 'Introverted'], 38 | 'S': ['Sensing', 'Sensor'], 39 | 'N': ['iNtuition', 'iNtuitor', 'iNtuitive'], 40 | 'F': ['Feeling', 'Feeler'], 41 | 'T': ['Thinking', 'Thinker'], 42 | 'P': ['Perceiving', 'Perceiver'], 43 | 'J': ['Judging', 'Judger'] 44 | } 45 | 46 | _cognitive_function_names = { 47 | 'Se': 'Extraverted Sensing', 48 | 'Si': 'Introverted Sensing', 49 | 'Ne': 'Extraverted iNtuition', 50 | 'Ni': 'Introverted iNtuition', 51 | 'Fe': 'Extraverted Feeling', 52 | 'Fi': 'Introverted Feeling', 53 | 'Te': 'Extraverted Thinking', 54 | 'Ti': 'Introverted Thinking' 55 | } 56 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | # test.py 2 | 3 | def create_sample(function, argument, sample_space): 4 | sample_results = {} 5 | 6 | for i in range(sample_space): 7 | result = str(function(argument)) 8 | 9 | if sample_results.has_key(result): 10 | sample_results[result] += 1 11 | else: 12 | sample_results[result] = 1 13 | 14 | for result in sample_results.keys(): 15 | sample_results[result] /= float(sample_space) 16 | 17 | return sample_results 18 | 19 | 20 | def run_trial(function, argument, trials, sample_space): 21 | trial_results = {} 22 | 23 | for i in range(trials): 24 | sample = create_sample(function, argument, sample_space) 25 | 26 | for result in sample.keys(): 27 | if trial_results.has_key(result): 28 | trial_results[result] += sample[result] 29 | else: 30 | trial_results[result] = sample[result] 31 | 32 | for result in trial_results.keys(): 33 | trial_results[result] /= float(trials) 34 | 35 | return trial_results 36 | 37 | 38 | def output_results(result_a, result_b): 39 | personality_type_probabilities = { 40 | 'ESTJ': 0.13, 41 | 'ESFJ': 0.12, 42 | 'ISTJ': 0.085, 43 | 'ISFJ': 0.07, 44 | 45 | 'ESTP': 0.1, 46 | 'ESFP': 0.11, 47 | 'ISTP': 0.06, 48 | 'ISFP': 0.06, 49 | 50 | 'ENFJ': 0.04, 51 | 'ENFP': 0.07, 52 | 'INFJ': 0.01, 53 | 'INFP': 0.02, 54 | 55 | 'ENTJ': 0.04, 56 | 'ENTP': 0.045, 57 | 'INTJ': 0.015, 58 | 'INTP': 0.025, 59 | } 60 | 61 | personality_types = [ 62 | 'ESTJ', 'ESFJ', 'ISTJ', 'ISFJ', 63 | 'ESTP', 'ESFP', 'ISTP', 'ISFP', 64 | 'ENFJ', 'ENFP', 'INFJ', 'INFP', 65 | 'ENTJ', 'ENTP', 'INTJ', 'INTP' 66 | ] 67 | 68 | header = '{:^9} {:^9} {:^9} {:10} {:^9} {:10}'.format('Type', 'Expected', 'Result A', '', 'Result B', '') 69 | 70 | print header 71 | print len(header) * '-' 72 | 73 | result_a_accuracy = result_b_accuracy = 0 74 | 75 | for personality_type in personality_types: 76 | result_a_difference = personality_type_probabilities[personality_type] - result_a[personality_type] 77 | result_b_difference = personality_type_probabilities[personality_type] - result_b[personality_type] 78 | 79 | if abs(result_a_difference) < abs(result_b_difference): 80 | result_a_accuracy += 1 81 | elif abs(result_a_difference) > abs(result_b_difference): 82 | result_b_accuracy += 1 83 | else: 84 | result_a_accuracy += 1 85 | result_b_accuracy += 1 86 | 87 | print '{:^9} {:<9f} {:<9f} {:<+10f} {:<9f} {:<+10f}'.format(personality_type, personality_type_probabilities[personality_type], \ 88 | result_a[personality_type], result_a_difference, result_b[personality_type], result_b_difference) 89 | 90 | print 91 | print 'Result A accuracy: {}/{} ({:.2%})'.format(result_a_accuracy, len(personality_types), result_a_accuracy / float(len(personality_types))) 92 | print 'Result B accuracy: {}/{} ({:.2%})'.format(result_b_accuracy, len(personality_types), result_b_accuracy / float(len(personality_types))) 93 | 94 | 95 | def test(trials=100, sample_space=100): 96 | from personality import Personality 97 | 98 | result_a = run_trial(Personality, False, trials, sample_space) 99 | result_b = run_trial(Personality, True, trials, sample_space) 100 | output_results(result_a, result_b) 101 | -------------------------------------------------------------------------------- /personality.py: -------------------------------------------------------------------------------- 1 | # personality.py 2 | 3 | """Module containing a personality type class. 4 | 5 | This module currently contains classes pertaining to the Myers-Briggs Type 6 | Indicator and Jungian Cognitive Functions. Currently adding functionality for 7 | the Keirsey Temperament Sorter. Another model of personality type will be added in 8 | the future, namely the Enneagram of Personality. 9 | 10 | Author: Adei Josol 11 | 12 | """ 13 | 14 | PREF_STR_MAX = 100 15 | 16 | class Personality: 17 | 18 | temperament_probabilities = { 19 | 'SP': {'All': 0.33, 'Male': 0.34, 'Female': 0.32}, 20 | 'SJ': {'All': 0.405, 'Male': 0.375, 'Female': 0.435}, 21 | 'NF': {'All': 0.14, 'Male': 0.105, 'Female': 0.175}, 22 | 'NT': {'All': 0.125, 'Male': 0.18, 'Female': 0.07} 23 | } 24 | 25 | personality_type_probabilities = { 26 | 'SP': { 27 | 'ESFP': {'All': 0.11, 'Male': 0.08, 'Female': 0.14}, 28 | 'ESTP': {'All': 0.1, 'Male': 0.125, 'Female': 0.075}, 29 | 'ISFP': {'All': 0.06, 'Male': 0.05, 'Female': 0.07}, 30 | 'ISTP': {'All': 0.06, 'Male': 0.085, 'Female': 0.035} 31 | }, 32 | 'SJ': { 33 | 'ESFJ': {'All': 0.12, 'Male': 0.07, 'Female': 0.17}, 34 | 'ESTJ': {'All': 0.13, 'Male': 0.16, 'Female': 0.1}, 35 | 'ISFJ': {'All': 0.07, 'Male': 0.04, 'Female': 0.1}, 36 | 'ISTJ': {'All': 0.085, 'Male': 0.105, 'Female': 0.065} 37 | }, 38 | 'NF': { 39 | 'ENFP': {'All': 0.07, 'Male': 0.06, 'Female': 0.08}, 40 | 'ENFJ': {'All': 0.04, 'Male': 0.025, 'Female': 0.055}, 41 | 'INFP': {'All': 0.02, 'Male': 0.015, 'Female': 0.025}, 42 | 'INFJ': {'All': 0.01, 'Male': 0.005, 'Female': 0.015} 43 | }, 44 | 'NT': { 45 | 'ENTP': {'All': 0.045, 'Male': 0.06, 'Female': 0.03}, 46 | 'ENTJ': {'All': 0.04, 'Male': 0.055, 'Female': 0.025}, 47 | 'INTP': {'All': 0.025, 'Male': 0.04, 'Female': 0.01}, 48 | 'INTJ': {'All': 0.015, 'Male': 0.025, 'Female': 0.005} 49 | } 50 | } 51 | 52 | 53 | def __init__(self, gender='All'): 54 | self.temperament = self.set_temperament(gender) 55 | self.personality_type = self.set_personality_type(self.temperament, gender) 56 | self.preference_strengths = self.set_preference_strengths(self.personality_type) 57 | self.cognitive_functions = self.set_cognitive_functions(self.personality_type) 58 | 59 | 60 | def __str__(self): 61 | return self.personality_type 62 | 63 | 64 | def set_temperament(self, gender): 65 | import random 66 | 67 | probability = 0 68 | while probability <= 0: # probability can never be <= 0 69 | probability = abs(1 - random.random()) # results in range (0.0, 1.0] 70 | boundary = 0 71 | 72 | # find which temperament range probability lies 73 | for temperament in self.temperament_probabilities.keys(): 74 | if boundary < probability <= boundary + self.temperament_probabilities[temperament][gender]: 75 | return temperament 76 | boundary += self.temperament_probabilities[temperament][gender] 77 | 78 | 79 | def set_personality_type(self, temperament, gender): 80 | import random 81 | 82 | probability = 0 83 | while probability <= 0: 84 | probability = abs(1 - random.random()) 85 | boundary = 0 86 | 87 | # find which personality type range probability lies 88 | for personality_type in self.personality_type_probabilities[temperament].keys(): 89 | personality_type_probability = self.personality_type_probabilities[temperament][personality_type][gender] / self.temperament_probabilities[temperament][gender] 90 | if boundary < probability <= boundary + personality_type_probability: 91 | return personality_type 92 | boundary += personality_type_probability 93 | 94 | 95 | def set_preference_strengths(self, personality_type): 96 | import random 97 | 98 | personality_type = list(personality_type) 99 | preference_strengths = {} 100 | 101 | for preference in personality_type: 102 | preference_strengths[preference] = random.randint(PREF_STR_MAX / 2 + 1, PREF_STR_MAX) 103 | 104 | return preference_strengths 105 | 106 | 107 | def set_cognitive_functions(self, personality_type): 108 | preference = { 109 | 'Attitude': 0, 110 | 'Perceiving': 1, 111 | 'Judging': 2, 112 | 'Lifestyle': 3 113 | } 114 | 115 | personality_type = list(personality_type) 116 | cognitive_functions = {} 117 | 118 | if personality_type[preference['Attitude']] == 'E': 119 | if personality_type[preference['Lifestyle']] == 'P': 120 | if personality_type[preference['Perceiving']] == 'S': 121 | cognitive_functions['Dominant'] = 'Se' 122 | cognitive_functions['Inferior'] = 'Ni' 123 | else: 124 | cognitive_functions['Dominant'] = 'Ne' 125 | cognitive_functions['Inferior'] = 'Si' 126 | if personality_type[preference['Judging']] == 'F': 127 | cognitive_functions['Auxiliary'] = 'Fi' 128 | cognitive_functions['Tertiary'] = 'Te' 129 | else: 130 | cognitive_functions['Auxiliary'] = 'Ti' 131 | cognitive_functions['Tertiary'] = 'Fe' 132 | else: 133 | if personality_type[preference['Judging']] == 'F': 134 | cognitive_functions['Dominant'] = 'Fe' 135 | cognitive_functions['Inferior'] = 'Ti' 136 | else: 137 | cognitive_functions['Dominant'] = 'Te' 138 | cognitive_functions['Inferior'] = 'Fi' 139 | if personality_type[preference['Perceiving']] == 'S': 140 | cognitive_functions['Auxiliary'] = 'Si' 141 | cognitive_functions['Tertiary'] = 'Ne' 142 | else: 143 | cognitive_functions['Auxiliary'] = 'Ni' 144 | cognitive_functions['Tertiary'] = 'Se' 145 | else: 146 | if personality_type[preference['Lifestyle']] == 'P': 147 | if personality_type[preference['Perceiving']] == 'S': 148 | cognitive_functions['Auxiliary'] = 'Se' 149 | cognitive_functions['Tertiary'] = 'Ni' 150 | else: 151 | cognitive_functions['Auxiliary'] = 'Ne' 152 | cognitive_functions['Tertiary'] = 'Si' 153 | if personality_type[preference['Judging']] == 'F': 154 | cognitive_functions['Dominant'] = 'Fi' 155 | cognitive_functions['Inferior'] = 'Te' 156 | else: 157 | cognitive_functions['Dominant'] = 'Ti' 158 | cognitive_functions['Inferior'] = 'Fe' 159 | else: 160 | if personality_type[preference['Judging']] == 'F': 161 | cognitive_functions['Auxiliary'] = 'Fe' 162 | cognitive_functions['Tertiary'] = 'Ti' 163 | else: 164 | cognitive_functions['Auxiliary'] = 'Te' 165 | cognitive_functions['Tertiary'] = 'Fi' 166 | if personality_type[preference['Perceiving']] == 'S': 167 | cognitive_functions['Dominant'] = 'Si' 168 | cognitive_functions['Inferior'] = 'Ne' 169 | else: 170 | cognitive_functions['Dominant'] = 'Ni' 171 | cognitive_functions['Inferior'] = 'Se' 172 | 173 | return cognitive_functions 174 | --------------------------------------------------------------------------------