morelists 0.1.1__py3-none-any.whl → 0.1.2__py3-none-any.whl

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.
morelists/__init__.py CHANGED
@@ -1,10 +1,29 @@
1
1
  import time
2
+ import json
2
3
 
3
4
  class GameList():
4
- def __init__(self, list = {}, expirationList = {}, flippedList = {}, freeze = False, deltaTime = 0):
5
- self.list = list
6
- self.expirationList = expirationList
7
- self.flippedList = flippedList
5
+ def __init__(self, list = None, expirationList = None, flippedList = None, freeze = False, deltaTime = 0):
6
+ """
7
+ Creates a new GameList
8
+
9
+ Useful when you want to add, subtract, multiply, and divide items
10
+ inside a list to calculate strength of effect or other things.
11
+ Comes with a built-in expiration date for easy use.
12
+
13
+ Perfect for game engine with changing stats like adding buffs and debuffs.
14
+
15
+ Should not receive any arguments without experienced knowledge of the library.
16
+
17
+ Keyword arguments:
18
+ list -- the starting list (default None)
19
+ expirationList -- the starting list tracking expiration dates (default None)
20
+ flippedList -- inverted list, used for faster lookup (default None)
21
+ freeze -- preserve the list and stops the built-in expiration date deletor (default False)
22
+ deltaTime -- tells the list how much behind it is in time. Used in updateToPresent() (default 0)
23
+ """
24
+ self.list: dict = list if list != None else {}
25
+ self.expirationList: dict = expirationList if expirationList != None else {}
26
+ self.flippedList: dict = flippedList if flippedList != None else {}
8
27
 
9
28
  self.addValue = 0
10
29
  self.subtractValue = 0
@@ -19,17 +38,43 @@ class GameList():
19
38
  self.deltaTime = deltaTime
20
39
 
21
40
 
41
+ def safeSum(self):
42
+ try:
43
+ return (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue
44
+ except ZeroDivisionError:
45
+ print("[WARNING]: GameList can't sum the list because of a ZeroDivisionError. Defaulted the sum value to be 0.")
46
+ return 0
47
+
48
+
22
49
  def add(self, item, expires = -1):
50
+ """
51
+ Adds a item to the list.
52
+
53
+ Keyword arguments:
54
+ item -- item you wish to add. Format: {"name":"nameHere", "type":"add/subtract/multiply/divide", "value":float}
55
+ expires -- in seconds on how long until it expires and gets deleted. Set it to -1 to allow it to exist forever (default -1)
56
+ """
57
+ immortal = True if expires == -1 else False
23
58
  perf_counter = time.time()
24
- if expires != -1:
25
- expires += perf_counter
59
+ expires += perf_counter
26
60
  self.list[expires] = {"name":item.get("name", ""), "type":item.get("type", "add"), "value":item.get("value", 0)}
61
+
62
+
27
63
  if self.list[expires]["type"] not in ["add", "subtract", "multiply", "divide"]:
28
- self.list[expires]["type"] = "add"
64
+ print(f"[WARNING]: GameList only supports add/subtract/multiply/divide types. Your input type: {self.list[expires]["type"]}. Defaulting to add type.")
65
+ self.list[expires]["type"] = "add"
66
+
67
+ if not "value" in item:
68
+ defaultValue = 0 if self.list[expires]["type"] in ["add", "subtract"] else 1
69
+ self.list[expires]["value"] = defaultValue
70
+ print(f"[WARNING]: GameList uses the key 'value' to store the value of each item. You seem to have not given it a value. Defaulted to {defaultValue}.")
29
71
 
30
- if expires != -1:
72
+ if self.list[expires]["name"] == "":
73
+ print(f'[WARNING]: GameList uses the key \'name\' to track items. You seem to have not given it a value. This will make it hard to track and pop at a later time (before its expiration date). Defaulted to "".')
74
+
75
+ if not immortal:
31
76
  self.expirationList[expires] = self.list[expires]
32
- self.flippedList[str(self.list[expires])] = expires
77
+ self.flippedList[json.dumps(self.list[expires], sort_keys=True)] = expires
33
78
 
34
79
  if item["type"] == "add":
35
80
  self.addValue += item["value"]
@@ -40,16 +85,25 @@ class GameList():
40
85
  elif item["type"] == "divide":
41
86
  self.divideValue += (item["value"] - 1)
42
87
 
43
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
88
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
44
89
 
45
90
  def unsafeAdd(self, item, expires = -1):
91
+ """
92
+ Adds a item to the list using a more unsafe method.
93
+
94
+ Only use this if you know what you are doing!
95
+
96
+ Keyword arguments:
97
+ item -- item you wish to add. Format: {"name":"nameHere", "type":"add/subtract/multiply/divide", "value":float}
98
+ expires -- in seconds on how long until it expires and gets deleted. Set it to -1 to allow it to exist forever (default -1)
99
+ """
100
+ immortal = True if expires == -1 else False
46
101
  perf_counter = time.time()
47
- if expires != -1:
48
- expires += perf_counter
102
+ expires += perf_counter
49
103
  self.list[expires] = item
50
- if expires != -1:
104
+ if not immortal:
51
105
  self.expirationList[expires] = self.list[expires]
52
- self.flippedList[str(item)] = expires
106
+ self.flippedList[json.dumps(item, sort_keys=True)] = expires
53
107
 
54
108
  if item["type"] == "add":
55
109
  self.addValue += item["value"]
@@ -60,10 +114,15 @@ class GameList():
60
114
  elif item["type"] == "divide":
61
115
  self.divideValue += (item["value"] - 1)
62
116
 
63
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
117
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
64
118
 
65
119
 
66
- def calculateSum(self):
120
+ def calculateSumWithoutUpdate(self):
121
+ """
122
+ Calculates the sum of the list without checking for expired items
123
+
124
+ Use only if you want to access the sum without updating
125
+ """
67
126
  self.addValue = 0
68
127
  self.subtractValue = 0
69
128
  self.multiplyValue = 1
@@ -77,11 +136,20 @@ class GameList():
77
136
  self.multiplyValue += (item["value"] - 1)
78
137
  elif item["type"] == "divide":
79
138
  self.divideValue += (item["value"] - 1)
80
- return (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue
139
+
140
+ return self.safeSum()
81
141
 
82
142
 
83
143
 
84
144
  def update(self):
145
+ """
146
+ Updates the list and removes any expires items.
147
+
148
+ This is already called upon when accessing the sum or history.
149
+ This function doesn't need to be by the user.
150
+ """
151
+
152
+ # update() ignore the reeze flag because it's assumed the user is calling it with the purpose of updating it manually
85
153
  try:
86
154
  expiration = min(self.expirationList.keys())
87
155
  while expiration < time.time():
@@ -94,75 +162,180 @@ class GameList():
94
162
  else:
95
163
  self.divideValue -= (self.list[expiration]["value"] - 1)
96
164
 
97
- del self.flippedList[str(self.list[expiration])]
165
+ del self.flippedList[json.dumps(self.list[expiration], sort_keys=True)]
98
166
  del self.list[expiration]
99
167
 
100
- object.__getattribute__(self, "history").append((expiration, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
168
+ object.__getattribute__(self, "history").append((expiration, self.list, self.expirationList, self.flippedList, self.safeSum()))
101
169
  expiration = min(self.expirationList.keys())
102
- except ValueError:
103
- pass
170
+ except ValueError as e:
171
+ print(f"[WARNING]: While updating the list, a new error appeared: {e}")
104
172
 
105
173
  def pause(self):
174
+ """
175
+ Prevents the list from auto-updating and prevents deletions of expired items without user input.
176
+ """
106
177
  self.freeze = True
107
178
 
108
179
  def resume(self):
180
+ """
181
+ Resumes the list to auto-update and delete expired items automatically.
182
+ """
109
183
  self.freeze = False
110
184
 
111
185
  def updateToPresent(self):
112
- pass
186
+ """
187
+ Updates each item in the list to match if the list was in the present. Setting deltaTime changes how much this affects the list.
188
+
189
+ Only use this if you are experienced and know what you are doing.
190
+ """
191
+ newList = {}
192
+ for key, value in self.list.items():
193
+ newList[key + self.deltaTime] = value
194
+ self.deltaTime = 0
113
195
 
114
196
  def restoreState(self, t) -> "GameList":
197
+ """
198
+ Creates a new GameList from the history of the list. Useful if you want to track previous sum values and such.
199
+
200
+ Keyword arguments:
201
+ t -- the time you want the new list to be based on
202
+ """
115
203
  self.update()
116
204
  lastItem = None
117
205
  for item in self.history:
118
206
  if item[0] < t:
119
207
  lastItem = item
208
+ else:
209
+ break
120
210
 
121
211
  if lastItem == None:
122
212
  return GameList()
123
213
  else:
124
214
  return GameList(lastItem[1], lastItem[2], False, time.time() - lastItem[0])
125
215
 
216
+ def getOldSums(self, t0, t1) -> list[tuple]:
217
+ """
218
+ Creates a list of tuples with the sum value from t0 -> t1.
219
+
220
+ Format: [(time, sum_value), ...]
221
+
222
+ Keyword arguments:
223
+ t0 -- the time you want the list to start
224
+ t1 -- the time you want the list to end
225
+ """
226
+ self.update()
227
+ items = []
228
+ for item in self.history:
229
+ if item[0] < t0:
230
+ items = [(item[0], item[4])]
231
+ elif item[0] < t1:
232
+ items.append((item[0], item[4]))
233
+ else:
234
+ break
235
+
236
+ return items
126
237
 
127
238
 
128
239
  def pop(self, name):
240
+ """
241
+ Pops a item from the list with the closest expiration date to the current time
242
+
243
+ Keyword arguments:
244
+ name -- the name you gave the item in the list
245
+ """
129
246
  perf_counter = time.time()
130
- pops = [value for value in self.list.values() if value["name"] == name]
131
- pops.sort(key=lambda a: a["expires"])
247
+ pops = [(key, value) for key, value in self.list.items() if value["name"] == name]
248
+ pops.sort(key=lambda a: a[0])
132
249
  if pops:
133
- del self.list[self.flippedList[str(pops[0])]]
134
- if self.flippedList[str(pops[0])] in self.expirationList: del self.expirationList[self.flippedList[str(pops[0])]]
135
- del self.flippedList[str(pops[0])]
136
- self.calculateSum()
137
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
250
+ stringedList = json.dumps(pops[0][1], sort_keys=True)
251
+
252
+ item = self.list[self.flippedList[stringedList]]
253
+ del self.list[self.flippedList[stringedList]]
254
+ if self.flippedList[stringedList] in self.expirationList: del self.expirationList[self.flippedList[stringedList]]
255
+ del self.flippedList[stringedList]
256
+
257
+ if item["type"] == "add":
258
+ self.addValue -= item["value"]
259
+ elif item["type"] == "subtract":
260
+ self.subtractValue -= item["value"]
261
+ elif item["type"] == "multiply":
262
+ self.multiplyValue -= (item["value"] - 1)
263
+ else:
264
+ self.divideValue -= (item["value"] - 1)
265
+
266
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
138
267
 
139
268
  def popAny(self, name):
269
+ """
270
+ Pops a item from the list with no regards for expiration date
271
+
272
+ Keyword arguments:
273
+ name -- the name you gave the item in the list
274
+ """
140
275
  perf_counter = time.time()
141
276
  pops = [value for value in self.list.values() if value["name"] == name]
142
277
  if pops:
143
- del self.list[self.flippedList[str(pops[0])]]
144
- if self.flippedList[str(pops[0])] in self.expirationList: del self.expirationList[self.flippedList[str(pops[0])]]
145
- del self.flippedList[str(pops[0])]
146
- self.calculateSum()
147
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
278
+ stringedList = json.dumps(pops[0], sort_keys=True)
279
+
280
+ item = self.list[self.flippedList[stringedList]]
281
+ del self.list[self.flippedList[stringedList]]
282
+ if self.flippedList[stringedList] in self.expirationList: del self.expirationList[self.flippedList[stringedList]]
283
+ del self.flippedList[stringedList]
284
+
285
+ if item["type"] == "add":
286
+ self.addValue -= item["value"]
287
+ elif item["type"] == "subtract":
288
+ self.subtractValue -= item["value"]
289
+ elif item["type"] == "multiply":
290
+ self.multiplyValue -= (item["value"] - 1)
291
+ else:
292
+ self.divideValue -= (item["value"] - 1)
293
+
294
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
148
295
 
149
296
  def popAll(self, name):
297
+ """
298
+ Pops every item from the list with the given name
299
+
300
+ Keyword arguments:
301
+ name -- the name you gave the item(s) in the list
302
+ """
150
303
  perf_counter = time.time()
151
304
  pops = [value for value in self.list.values() if value["name"] == name]
152
305
  if pops:
153
306
  for x in range(len(pops)):
154
- del self.list[self.flippedList[str(pops[x])]]
155
- if self.flippedList[str(pops[x])] in self.expirationList: del self.expirationList[self.flippedList[str(pops[x])]]
156
- del self.flippedList[str(pops[x])]
157
- self.calculateSum()
158
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
307
+ stringedList = json.dumps(pops[x], sort_keys=True)
308
+
309
+
310
+ item = self.list[self.flippedList[stringedList]]
311
+ del self.list[self.flippedList[stringedList]]
312
+ if self.flippedList[stringedList] in self.expirationList: del self.expirationList[self.flippedList[stringedList]]
313
+ del self.flippedList[stringedList]
314
+
315
+ if item["type"] == "add":
316
+ self.addValue -= item["value"]
317
+ elif item["type"] == "subtract":
318
+ self.subtractValue -= item["value"]
319
+ elif item["type"] == "multiply":
320
+ self.multiplyValue -= (item["value"] - 1)
321
+ else:
322
+ self.divideValue -= (item["value"] - 1)
323
+
324
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
159
325
 
160
326
  def remove(self, item):
327
+ """
328
+ Removes a specific item from the list (if it exists)
329
+
330
+ Keyword arguments:
331
+ name -- the name you gave the item(s) in the list
332
+ """
161
333
  perf_counter = time.time()
162
- if self.flippedList.get(str(item), None):
163
- del self.list[self.flippedList[str(item)]]
164
- if self.flippedList[str(item)] in self.expirationList: del self.expirationList[self.flippedList[str(item)]]
165
- del self.flippedList[str(item)]
334
+ stringedList = json.dumps(item, sort_keys=True)
335
+ if self.flippedList.get(stringedList, None):
336
+ del self.list[self.flippedList[stringedList]]
337
+ if self.flippedList[stringedList] in self.expirationList: del self.expirationList[self.flippedList[stringedList]]
338
+ del self.flippedList[stringedList]
166
339
 
167
340
  if item["type"] == "add":
168
341
  self.addValue -= item["value"]
@@ -173,14 +346,23 @@ class GameList():
173
346
  else:
174
347
  self.divideValue -= (item["value"] - 1)
175
348
 
176
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
349
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
177
350
 
178
351
  def unsafeRemove(self, item):
352
+ """
353
+ Removes a specific item from the list (if it exists)
354
+
355
+ More unsafe compared to remove(item), so use only if you know what you are doing!
356
+
357
+ Keyword arguments:
358
+ name -- the name you gave the item(s) in the list
359
+ """
179
360
  perf_counter = time.time()
180
361
  if item in self.list.values():
181
- del self.list[dict(self.flippedList[str(item)])]
182
- if dict(self.flippedList[str(item)]) in self.expirationList: del self.expirationList[dict(self.flippedList[str(item)])]
183
- del self.flippedList[str(item)]
362
+ stringedList = json.dumps(item, sort_keys=True)
363
+ del self.list[dict(self.flippedList[stringedList])]
364
+ if dict(self.flippedList[stringedList]) in self.expirationList: del self.expirationList[dict(self.flippedList[stringedList])]
365
+ del self.flippedList[stringedList]
184
366
 
185
367
  if item["type"] == "add":
186
368
  self.addValue -= item["value"]
@@ -191,9 +373,17 @@ class GameList():
191
373
  else:
192
374
  self.divideValue -= (item["value"] - 1)
193
375
 
194
- object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, (self.addValue - self.subtractValue) * self.multiplyValue / self.divideValue))
376
+ object.__getattribute__(self, "history").append((perf_counter, self.list, self.expirationList, self.flippedList, self.safeSum()))
195
377
 
196
378
  def __getattribute__(self, name):
379
+ """
380
+ Retrieves attributes from the class
381
+
382
+ Updates the list if you grab the sum value or the history data
383
+
384
+ Keyword arguments:
385
+ name -- the name of the attribute you want to grab
386
+ """
197
387
  if name == "sum":
198
388
  if not object.__getattribute__(self, "freeze"):
199
389
  self.update()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: morelists
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: A small and easy list you can add together like a math equation and has a expiration date for items. Mostly useful for games with stats from multiple sources. More lists will come soon.
5
5
  Home-page: https://github.com/EmanuelNorsk/enlist
6
6
  Author: Emanuel Odén Hesselroth
@@ -0,0 +1,6 @@
1
+ morelists/__init__.py,sha256=b46BNQD_evFdrX8YU5ignMxU6ZBDIpEx0KbXoQCY8PI,16729
2
+ morelists-0.1.2.dist-info/licenses/LICENSE,sha256=-ASFHlrne1rk8zV57Qj01X2JB-D67ZHPMv1PtQhrbN8,32
3
+ morelists-0.1.2.dist-info/METADATA,sha256=JtoS_qxKDCJ8q_r3ootsTvDI_1E38VcM7jx4dVHaMvk,681
4
+ morelists-0.1.2.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
5
+ morelists-0.1.2.dist-info/top_level.txt,sha256=Zd7NosYzor-RcH_aD86FXJa3fQzWunYA4_FQS3Yodqo,10
6
+ morelists-0.1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.1)
2
+ Generator: setuptools (79.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +0,0 @@
1
- morelists/__init__.py,sha256=2ADwt9v-X0M-agPoRLKfELfbIAzxxcjtSvyL_ltJIeo,9344
2
- morelists-0.1.1.dist-info/licenses/LICENSE,sha256=-ASFHlrne1rk8zV57Qj01X2JB-D67ZHPMv1PtQhrbN8,32
3
- morelists-0.1.1.dist-info/METADATA,sha256=2AmxOSbe5kT0sziBKdoebqVI9DCtjqAx4i6A2gSGt8Q,681
4
- morelists-0.1.1.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
5
- morelists-0.1.1.dist-info/top_level.txt,sha256=Zd7NosYzor-RcH_aD86FXJa3fQzWunYA4_FQS3Yodqo,10
6
- morelists-0.1.1.dist-info/RECORD,,