linguistics-evolution-simulator 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (17) hide show
  1. linguistics_evolution_simulator-0.1.0/PKG-INFO +26 -0
  2. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/__init__.py +0 -0
  3. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/data/civilisation.json +74 -0
  4. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/data/civilisation_init.json +12 -0
  5. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/data/events.json +75 -0
  6. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/data/intro.txt +6 -0
  7. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/data/outro.txt +2 -0
  8. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/data/words.json +41 -0
  9. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator/main.py +281 -0
  10. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator.egg-info/PKG-INFO +26 -0
  11. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator.egg-info/SOURCES.txt +15 -0
  12. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator.egg-info/dependency_links.txt +1 -0
  13. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator.egg-info/entry_points.txt +2 -0
  14. linguistics_evolution_simulator-0.1.0/linguistics_evolution_simulator.egg-info/top_level.txt +1 -0
  15. linguistics_evolution_simulator-0.1.0/pyproject.toml +16 -0
  16. linguistics_evolution_simulator-0.1.0/readme.md +19 -0
  17. linguistics_evolution_simulator-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: linguistics-evolution-simulator
3
+ Version: 0.1.0
4
+ Summary: A small civilisation and language evolution simulator.
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+
8
+ ## Features
9
+ This is an attempt at representing linguistic evolution in a human civilisation! It evolves 20 words through 100-year iterations.
10
+
11
+ The game loop is in main; at the beginning, a "civilisation" is generated with random parameters so as to give it unique words for resources; this might also become a game mechanic in the future. Afterwards, a quantity of words "evolve" depending on the modifiers that randomly selected events produce.
12
+
13
+ With regards to the string of "plague" messages, this is to ensure that the population doesn't spiral out of control and lead to many word mutations all at once.
14
+
15
+
16
+ ## AI use declaration
17
+ As I said in the project description, virtually none of the code had AI input; as far as I can remember, all the code was written myself, with AI only acting occasionally as a tool that I use for better-quality brainstorming and planning.
18
+
19
+ However, there was one major task that I had to rely on AI for guidance, which is the publishing to PyPI step in preparation for shipping. I am personally very inexperienced with the whole project lifecycle, and especially shipping, so I had to rely on it to guide me through this process of packing everything in and replacing some file paths in the source code. In any case, this is good project experience and something that I learned!
20
+
21
+
22
+ ## Installation
23
+ Install with pipx:
24
+
25
+ ```bash
26
+ pipx install linguistics-evolution-simulator
@@ -0,0 +1,74 @@
1
+ {
2
+ "geographies": [
3
+ "Forest",
4
+ "Plains",
5
+ "Desert/Steppe",
6
+ "Mountains/Valley",
7
+ "Wetlands (Ocean, River)"
8
+ ],
9
+
10
+ "resources": {
11
+ "specific": {
12
+ "Forest": [
13
+ "Timber",
14
+ "Furs",
15
+ "Honey"
16
+ ],
17
+
18
+ "Plains": [
19
+ "Wheat",
20
+ "Barley",
21
+ "Oats",
22
+ "Horses",
23
+ "Cattle"
24
+ ],
25
+
26
+ "Desert/Steppe": [
27
+ "Dates",
28
+ "Ivory",
29
+ "Camels"
30
+ ],
31
+
32
+ "Mountains/Valley": [
33
+ "Stone",
34
+ "Marble",
35
+ "Limestone",
36
+ "Goats"
37
+ ],
38
+
39
+ "Wetlands (Ocean, River)": [
40
+ "Fish",
41
+ "Rice",
42
+ "Papyrus",
43
+ "Clay"
44
+ ]
45
+ },
46
+
47
+ "general": [
48
+ "Olives",
49
+ "Grapes",
50
+ "Salt",
51
+ "Iron",
52
+ "Copper",
53
+ "Tin",
54
+ "Lead",
55
+ "Silver",
56
+ "Gold",
57
+ "Coal",
58
+ "Charcoal",
59
+ "Wool",
60
+ "Leather",
61
+ "Sheep",
62
+ "Pigs",
63
+ "Spices",
64
+ "Herbs",
65
+ "Dyes",
66
+ "Silk",
67
+ "Cotton"
68
+ ]
69
+ },
70
+
71
+ "quirks": {
72
+ "empty": "so far"
73
+ }
74
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "population": 719,
3
+ "geography": "Wetlands (Ocean, River)",
4
+ "mobility_level": 6,
5
+ "resources": [
6
+ "Clay",
7
+ "Fish",
8
+ "Gold",
9
+ "Spices",
10
+ "Dyes"
11
+ ]
12
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ "events": [
3
+ {
4
+ "event": "Conquest - the conquerors have introduced new words.",
5
+ "word_shift_modifier": 3,
6
+ "word_addition_modifier": 0,
7
+ "grammar_shift_modifier": 0,
8
+ "population_shift_modifier": -0.02
9
+ },
10
+
11
+ {
12
+ "event": "Slang - the youngsters, adding new vocabulary!",
13
+ "word_shift_modifier": 4,
14
+ "word_addition_modifier": 0,
15
+ "grammar_shift_modifier": 0,
16
+ "population_shift_modifier": 0
17
+ },
18
+
19
+ {
20
+ "event": "Trade - traders from all across the region bring their words.",
21
+ "word_shift_modifier": 1,
22
+ "word_addition_modifier": 0,
23
+ "grammar_shift_modifier": 0,
24
+ "population_shift_modifier": 0.01
25
+ },
26
+
27
+ {
28
+ "event": "Migration - other tribes and peoples have brought their tongues with them.",
29
+ "word_shift_modifier": 2,
30
+ "word_addition_modifier": 0,
31
+ "grammar_shift_modifier": 0,
32
+ "population_shift_modifier": 0.1
33
+ },
34
+
35
+ {
36
+ "event": "Isolation - less people to talk with, less words get made up.",
37
+ "word_shift_modifier": -1,
38
+ "word_addition_modifier": 0,
39
+ "grammar_shift_modifier": 0,
40
+ "population_shift_modifier": 0
41
+ },
42
+
43
+ {
44
+ "event": "Writing - words being written down offer a spelling that is less modifiable.",
45
+ "word_shift_modifier": -1,
46
+ "word_addition_modifier": 0,
47
+ "grammar_shift_modifier": 0,
48
+ "population_shift_modifier": 0
49
+ },
50
+
51
+ {
52
+ "event": "Political Unification - the new regime is making efforts to unify the language.",
53
+ "word_shift_modifier": -2,
54
+ "word_addition_modifier": 0,
55
+ "grammar_shift_modifier": 0,
56
+ "population_shift_modifier": 0
57
+ },
58
+
59
+ {
60
+ "event": "Education - More people know how to read and write standard words, and they don't change as much.",
61
+ "word_shift_modifier": -4,
62
+ "word_addition_modifier": 0,
63
+ "grammar_shift_modifier": 0,
64
+ "population_shift_modifier": 0
65
+ },
66
+
67
+ {
68
+ "event": "Plague - People are dying in droves, and many words are dying off.",
69
+ "word_shift_modifier": -3,
70
+ "word_addition_modifier": 0,
71
+ "grammar_shift_modifier": 0,
72
+ "population_shift_modifier": -0.2
73
+ }
74
+ ]
75
+ }
@@ -0,0 +1,6 @@
1
+ Welcome to the Linguistics Simulator!
2
+ This is a little mockup of how linguistics evolution can occur within human populations.
3
+ But a disclaimer first.
4
+ I am not a linguistics professor, so there probably are issues in terms of evolutionary accuracy.
5
+ I am open to any feedback if that's the case.
6
+ But sit back, relax, and see a little civilisation evolve!
@@ -0,0 +1,2 @@
1
+ Year 3000 is where this simulation ends. Nowhere near a realistic timescale, but here we are.
2
+ Hopefully you enjoyed this rudimentary demo! Perhaps consider trying it out again.
@@ -0,0 +1,41 @@
1
+ {
2
+ "general": [
3
+ "water",
4
+ "food",
5
+ "house",
6
+ "way",
7
+ "person",
8
+ "sleep",
9
+ "hand",
10
+ "world",
11
+ "life",
12
+ "day",
13
+ "time"
14
+ ],
15
+
16
+ "antiquity": [
17
+ "slave",
18
+ "forum",
19
+ "gods",
20
+ "chief",
21
+ "tribe"
22
+ ],
23
+
24
+ "medieval": [
25
+ "merchant",
26
+ "castle",
27
+ "king",
28
+ "village",
29
+ "knight"
30
+ ],
31
+
32
+ "modern": [
33
+ "factory",
34
+ "machine",
35
+ "country",
36
+ "city",
37
+ "clock"
38
+ ]
39
+
40
+
41
+ }
@@ -0,0 +1,281 @@
1
+ import random
2
+ import json
3
+ import time
4
+
5
+ from pathlib import Path
6
+ DATA_DIR = Path(__file__).parent / "data"
7
+
8
+ word_shift_modifier = 0 # number of words that are shifted per iteration
9
+ vowels = str()
10
+ consonants = str()
11
+ modified_words = list()
12
+
13
+ #loading some needed files
14
+ with open(DATA_DIR / "civilisation.json") as file:
15
+ data = json.load(file) #loading all potential environment data
16
+ with open(DATA_DIR / "words.json") as file:
17
+ word_pool = json.load(file)
18
+ with open(DATA_DIR / "events.json") as file:
19
+ all_events = json.load(file)
20
+
21
+ with open(DATA_DIR / "intro.txt", "r") as file:
22
+ intro_lines = file.readlines()
23
+ with open(DATA_DIR / "outro.txt", "r") as file:
24
+ outro_lines = file.readlines()
25
+
26
+
27
+
28
+ class Civilisation():
29
+ def __init__(self):
30
+ self.population = random.randint(100, 1000) # Sets beginning population of the civilisation
31
+ self.geography, self.mobility_level = set_geography() # Sets geographical features of the generated civilisation
32
+ self.resources = get_resources(self.geography) # Gets civilisation resources
33
+ self.words = generate_words(self.resources) # Generates word-like words + hardwired to initialise 20 words
34
+
35
+ self.events = None # variable for events - list of event dicts
36
+
37
+ self.write_to_json()
38
+
39
+ def write_to_json(self):
40
+ civilisation_data = {
41
+ "population": self.population,
42
+ "geography": self.geography,
43
+ "mobility_level": self.mobility_level,
44
+ "resources": self.resources,
45
+ }
46
+
47
+ with open(DATA_DIR / "civilisation_init.json", "w") as file:
48
+ json.dump(civilisation_data, file, indent=4)
49
+
50
+ def display_init(self):
51
+ print("\n--- CIVILISATION ---")
52
+ print(f"Population: {self.population}")
53
+ print(f"Geography: {self.geography}")
54
+ print(f"Mobility: {self.mobility_level}/10")
55
+ print(f"Resources: {', '.join(self.resources)}")
56
+
57
+ def display(self, year):
58
+ print("\n--- DASHBOARD ---")
59
+ print(f"Population: {self.population}")
60
+
61
+ if year < 1000:
62
+ era = "Antiquity"
63
+ elif 1000 < year < 2000:
64
+ era = "Medieval"
65
+ else:
66
+ era = "Modern"
67
+ print(f"Era: {era}")
68
+
69
+ print("\nWORDS")
70
+ for i, word in enumerate(self.words):
71
+ if i == 0:
72
+ print("--> General words")
73
+ elif i == 11:
74
+ print("\n--> Resource Words")
75
+ elif i == 16:
76
+ print("\n--> Era-Specific words")
77
+ print(f"{word}: {self.words[word]}")
78
+
79
+ print("\nCHANGES")
80
+ print(f"{word_shift_modifier} words were modified in this iteration.")
81
+ for i, word in enumerate(modified_words):
82
+ print(f"{i + 1}. {word["original"]} --> {word["changed"]}")
83
+
84
+ for i, event in enumerate(self.events):
85
+ print(f"\n{i + 1}.", event["event"])
86
+ print(f"Population change: {round(event["population_shift_modifier"] * 100)}%")
87
+
88
+ def iterate_event(self):
89
+ a = 0
90
+ self.events = []
91
+
92
+ for event in all_events["events"]:
93
+ if self.population > 3000:
94
+ self.events.append(all_events["events"][8])
95
+ continue
96
+ a = random.randint(0, 1)
97
+ if a == 1 and len(self.events) < 3:
98
+ self.events.append(event)
99
+
100
+ def iterate_population(self):
101
+ self.population += round(0.2 * self.population)
102
+ for event in self.events:
103
+ self.population += round(event["population_shift_modifier"] * self.population)
104
+
105
+ def iterate_words(self, year):
106
+ global word_shift_modifier
107
+ word_shift_modifier = 0
108
+
109
+ for event in self.events:
110
+ word_shift_modifier += event["word_shift_modifier"]
111
+
112
+ word_shift_modifier = max(0, min(word_shift_modifier, 10)) # Maximum 10 words changed per iteration
113
+
114
+
115
+ new_era_words = None
116
+
117
+ if year == 1000 or year == 2000:
118
+ if year == 1000:
119
+ new_era_words = word_pool["medieval"]
120
+ else:
121
+ new_era_words = word_pool["modern"]
122
+
123
+ old_words = list(self.words.keys())[-5:]
124
+
125
+ for word in old_words:
126
+ self.words.pop(word)
127
+
128
+ for word in new_era_words[:5]:
129
+ global vowels
130
+ global consonants
131
+ self.words[word] = make_word(vowels, consonants)
132
+
133
+ self.events.append({
134
+ "event": "New era, new words - Change of era! Last 5 era-specific words have changed.",
135
+ "population_shift_modifier": 0,
136
+ "word_shift_modifier": 0
137
+ })
138
+
139
+
140
+ count = 0
141
+ global modified_words
142
+ modified_words = []
143
+
144
+ words_to_change = random.sample(
145
+ list(self.words.keys()),
146
+ min(word_shift_modifier, len(self.words))
147
+ )
148
+
149
+ for word in words_to_change:
150
+ change = {
151
+ "original": self.words[word],
152
+ "changed": None
153
+ }
154
+
155
+ self.words[word] = mutate_word(self.words[word])
156
+
157
+ change["changed"] = self.words[word]
158
+ modified_words.append(change)
159
+
160
+ count += 1
161
+
162
+
163
+
164
+ #----------------------------------------------------------------------------------------
165
+
166
+
167
+
168
+ def set_geography():
169
+ geography = random.choice(data["geographies"])
170
+
171
+ if geography == "Forest":
172
+ mobility_level = random.randint(3, 6)
173
+ elif geography == "Plains":
174
+ mobility_level = random.randint(6, 9)
175
+ elif geography == "Desert/Steppe":
176
+ mobility_level = random.randint(7, 10)
177
+ elif geography == "Mountains/Valley":
178
+ mobility_level = random.randint(0, 3)
179
+ elif geography == "Wetlands (Ocean, River)":
180
+ mobility_level = random.randint(4, 7)
181
+ return geography, mobility_level
182
+
183
+ def get_resources(geography):
184
+ resource_count = 5
185
+
186
+ specific_resources = data["resources"]["specific"][geography]
187
+ general_resources = data["resources"]["general"]
188
+
189
+ resources = random.sample(specific_resources, 2)
190
+
191
+ remaining = resource_count - 2
192
+
193
+ resources += random.sample(general_resources, remaining)
194
+
195
+ return resources
196
+
197
+ def generate_words(resources):
198
+ words = dict()
199
+ for word in word_pool["general"]:
200
+ words[word] = None
201
+ for resource in resources:
202
+ words[resource] = None
203
+ for word in word_pool["antiquity"]:
204
+ words[word] = None
205
+
206
+ all_vowels = "aeiou"
207
+ all_consonants = "bcdfghjklmnpqrstvwxyz"
208
+
209
+ global vowels
210
+ global consonants
211
+ vowels = random.sample(all_vowels, 3)
212
+ consonants = random.sample(all_consonants, 10)
213
+
214
+ for word in words:
215
+ words[word] = make_word(vowels, consonants)
216
+
217
+ return words
218
+
219
+ def make_word(vowels, consonants):
220
+ word = ""
221
+ for _ in range(random.randint(2, 3)):
222
+ word += random.choice(consonants)
223
+ word += random.choice(vowels)
224
+
225
+ return word
226
+
227
+ def mutate_word(word):
228
+ vowels = "aeiou"
229
+ consonants = "bcdfghjklmnpqrstvwxyz"
230
+
231
+ index = random.randint(0, len(word) - 1)
232
+ old_letter = word[index]
233
+
234
+ if old_letter in vowels:
235
+ possible_letters = vowels
236
+ else:
237
+ possible_letters = consonants
238
+
239
+ new_letter = random.choice(possible_letters)
240
+
241
+ while new_letter == old_letter:
242
+ new_letter = random.choice(possible_letters)
243
+
244
+ return word[:index] + new_letter + word[index + 1:]
245
+
246
+
247
+
248
+ def main():
249
+ civilisation = Civilisation()
250
+ running = True
251
+ year = 0
252
+
253
+ while running:
254
+ if year == 0:
255
+ for line in intro_lines:
256
+ print(line, end="")
257
+ time.sleep(3)
258
+ print("\n")
259
+ print(f"\nYEAR {year}")
260
+ civilisation.display_init()
261
+ time.sleep(5)
262
+ year += 100
263
+
264
+ print(f"\nYEAR {year}")
265
+ civilisation.iterate_event() # Randomly gets events that are happening this iteration cycle
266
+ civilisation.iterate_population() # Changes civilisation population (mechanic related to some events)
267
+ civilisation.iterate_words(year) # Changes the words in the dashboard
268
+ civilisation.display(year) # Displays a dashboard
269
+ time.sleep(10) # 10 seconds for you to review the word changes in the dashboard
270
+
271
+ if year == 3000:
272
+ print("\n")
273
+ for line in outro_lines:
274
+ print(line, end="")
275
+ time.sleep(3)
276
+ break
277
+
278
+ year += 100
279
+
280
+ if __name__ == "__main__":
281
+ main()
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: linguistics-evolution-simulator
3
+ Version: 0.1.0
4
+ Summary: A small civilisation and language evolution simulator.
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+
8
+ ## Features
9
+ This is an attempt at representing linguistic evolution in a human civilisation! It evolves 20 words through 100-year iterations.
10
+
11
+ The game loop is in main; at the beginning, a "civilisation" is generated with random parameters so as to give it unique words for resources; this might also become a game mechanic in the future. Afterwards, a quantity of words "evolve" depending on the modifiers that randomly selected events produce.
12
+
13
+ With regards to the string of "plague" messages, this is to ensure that the population doesn't spiral out of control and lead to many word mutations all at once.
14
+
15
+
16
+ ## AI use declaration
17
+ As I said in the project description, virtually none of the code had AI input; as far as I can remember, all the code was written myself, with AI only acting occasionally as a tool that I use for better-quality brainstorming and planning.
18
+
19
+ However, there was one major task that I had to rely on AI for guidance, which is the publishing to PyPI step in preparation for shipping. I am personally very inexperienced with the whole project lifecycle, and especially shipping, so I had to rely on it to guide me through this process of packing everything in and replacing some file paths in the source code. In any case, this is good project experience and something that I learned!
20
+
21
+
22
+ ## Installation
23
+ Install with pipx:
24
+
25
+ ```bash
26
+ pipx install linguistics-evolution-simulator
@@ -0,0 +1,15 @@
1
+ pyproject.toml
2
+ readme.md
3
+ linguistics_evolution_simulator/__init__.py
4
+ linguistics_evolution_simulator/main.py
5
+ linguistics_evolution_simulator.egg-info/PKG-INFO
6
+ linguistics_evolution_simulator.egg-info/SOURCES.txt
7
+ linguistics_evolution_simulator.egg-info/dependency_links.txt
8
+ linguistics_evolution_simulator.egg-info/entry_points.txt
9
+ linguistics_evolution_simulator.egg-info/top_level.txt
10
+ linguistics_evolution_simulator/data/civilisation.json
11
+ linguistics_evolution_simulator/data/civilisation_init.json
12
+ linguistics_evolution_simulator/data/events.json
13
+ linguistics_evolution_simulator/data/intro.txt
14
+ linguistics_evolution_simulator/data/outro.txt
15
+ linguistics_evolution_simulator/data/words.json
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ linguistics-sim = linguistics_evolution_simulator.main:main
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "linguistics-evolution-simulator"
7
+ version = "0.1.0"
8
+ description = "A small civilisation and language evolution simulator."
9
+ readme = "readme.md"
10
+ requires-python = ">=3.10"
11
+
12
+ [project.scripts]
13
+ linguistics-sim = "linguistics_evolution_simulator.main:main"
14
+
15
+ [tool.setuptools.package-data]
16
+ linguistics_evolution_simulator = ["data/*.json", "data/*.txt"]
@@ -0,0 +1,19 @@
1
+ ## Features
2
+ This is an attempt at representing linguistic evolution in a human civilisation! It evolves 20 words through 100-year iterations.
3
+
4
+ The game loop is in main; at the beginning, a "civilisation" is generated with random parameters so as to give it unique words for resources; this might also become a game mechanic in the future. Afterwards, a quantity of words "evolve" depending on the modifiers that randomly selected events produce.
5
+
6
+ With regards to the string of "plague" messages, this is to ensure that the population doesn't spiral out of control and lead to many word mutations all at once.
7
+
8
+
9
+ ## AI use declaration
10
+ As I said in the project description, virtually none of the code had AI input; as far as I can remember, all the code was written myself, with AI only acting occasionally as a tool that I use for better-quality brainstorming and planning.
11
+
12
+ However, there was one major task that I had to rely on AI for guidance, which is the publishing to PyPI step in preparation for shipping. I am personally very inexperienced with the whole project lifecycle, and especially shipping, so I had to rely on it to guide me through this process of packing everything in and replacing some file paths in the source code. In any case, this is good project experience and something that I learned!
13
+
14
+
15
+ ## Installation
16
+ Install with pipx:
17
+
18
+ ```bash
19
+ pipx install linguistics-evolution-simulator
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+