db.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from tinydb import TinyDB, Query
  2. import pandas as pd
  3. import numpy as np
  4. from scipy import stats
  5. import matplotlib.pyplot as plt
  6. from datetime import datetime,date
  7. MarketDB = TinyDB('market.json')
  8. PlayerDB = TinyDB('player.json')
  9. def getDF(card=None,aDate=None,pruneOutliers=True):
  10. """
  11. Supply either a card identifier or a date for filter by.
  12. card can be an integer, which will pull from the card-num, or a string
  13. which will pull from the name field. It can also be a list of ints
  14. or strings, which will pull multiple cards histories.
  15. date can be either a datetime or string date formatted 'yyyy-mm-dd'
  16. """
  17. MarketDB = TinyDB('market.json')
  18. if card is not None:
  19. if isinstance(card,list):
  20. if isinstance(card[0],int):
  21. d=MarketDB.search(Query()['card-num'].one_of(card))
  22. else:
  23. d=MarketDB.search(Query()['name'].one_of(card))
  24. else:
  25. if isinstance(card,int):
  26. d=MarketDB.search(Query()['card-num']==card)
  27. else:
  28. d=MarketDB.search(Query()['name']==card)
  29. else:
  30. if isinstance(aDate,(datetime,date)):
  31. d=MarketDB.search(Query()['date']==aDate.strftime('%Y-%m-%d'))
  32. else:
  33. d=MarketDB.search(Query()['date']==aDate)
  34. df=pd.DataFrame(d)
  35. if pruneOutliers:
  36. df=df[np.abs(stats.zscore(df['cost'])) < 1.5]
  37. df.sort_values(by=['card-num','date'], ascending=[True,True], inplace=True)
  38. return df.round({'cost':2,'cost-min':0,'cost-max':0})
  39. def _hist(card=None,date=None,columns=['date','card-num','name','cost']):
  40. return getDF(card,date)[columns].to_string(index=False)
  41. def hist(card=None,date=None,columns=['date','card-num','name','cost']):
  42. print(_hist(card,date,columns))
  43. def plot(card=None,columns=['cost','cost-min','cost-max'],maxCost=None):
  44. """must use either card or date.
  45. card cand be card-num or name
  46. date can be a datetime type or a string like 'yyy-mm-dd'
  47. columns must be a list of any numeric fields in the MarketDB
  48. """
  49. df=getDF(card).plot(x='date',y=columns)
  50. plt.title(str(card))
  51. plt.xticks(rotation=45)
  52. plt.xlabel("Date")
  53. plt.ylabel("Cost")
  54. plt.ylim(0,maxCost)
  55. plt.show()
  56. def buyout():
  57. today=datetime.utcnow().strftime('%Y-%m-%d')
  58. PlayerCards=PlayerDB.search(Query().fragment({'date':today}))
  59. Stock=[None]*152
  60. for card in PlayerCards: Stock[card['card-num']]=card['stock']
  61. MarketDF = getDF(aDate=today)
  62. MarketCards=MarketDF.to_dict('records')
  63. total=0
  64. cardCount=0
  65. NeededCards=[]
  66. for card in MarketCards:
  67. if 'CRYSTAL' not in Stock[card['card-num']]:
  68. card['stock']=int(Stock[card['card-num']])
  69. card['needed']=10-card['stock']
  70. card['card-num']=card['card-num']
  71. card['total-cost']=card['needed']*card['cost']
  72. NeededCards.append(card)
  73. total+=card['total-cost']
  74. cardCount+=card['needed']
  75. print(f"{card['card-num']: <3} {card['name']: <20} {card['needed']: >2} {card['total-cost']}")
  76. print(f" Remaining Cards: {cardCount}")
  77. print(f"Total Gems Needed: {total}")