def get_foil_price(self, api, product_id, language_id): # NOTE: This is a rough algorithm, designed to be safe and not to sell aggressively. # 1) See filter parameters below. # 2) Set price to lowest + (median - lowest / 4), rounded to closest quarter Euro. # 3) Undercut price in own country if not contradicting 2) # 4) Never go below 0.25 for foils account = api.get_account()['account'] articles = api.get_articles( product_id, **{ 'isFoil': 'true', 'isAltered': 'false', 'isSigned': 'false', 'minCondition': 'GD', 'idLanguage': language_id }) keys = ['idArticle', 'count', 'price', 'condition', 'seller'] foil_articles = [{x: y for x, y in art.items() if x in keys} for art in articles] local_articles = [] for article in foil_articles: if article['seller']['address']['country'] == account[ 'country'] and article['seller']['username'] != account[ 'username']: local_articles.append(article) local_table_data = [] for article in local_articles: if article: local_table_data.append([ article['seller']['username'], article['seller']['address']['country'], article['condition'], article['count'], article['price'] ]) table_data = [] for article in foil_articles: if article: table_data.append([ article['seller']['username'], article['seller']['address']['country'], article['condition'], article['count'], article['price'] ]) median_price = PyMkmHelper.calculate_median(table_data, 3, 4) lowest_price = PyMkmHelper.calculate_lowest(table_data, 4) median_guided = PyMkmHelper.round_up_to_quarter( lowest_price + (median_price - lowest_price) / 4) if len(local_table_data) > 0: # Undercut if there is local competition lowest_in_country = PyMkmHelper.round_down_to_quarter( PyMkmHelper.calculate_lowest(local_table_data, 4)) return max(0.25, min(median_guided, lowest_in_country - 0.25)) else: # No competition in our country, set price a bit higher. return PyMkmHelper.round_up_to_quarter(median_guided * 1.2)
def get_price_for_product(self, product_id, rarity, is_foil, language_id=1, undercut_local_market=False, api=None): r = api.get_product(product_id) rounding_limit = self.get_rounding_limit_for_rarity(rarity) if not is_foil: trend_price = r['product']['priceGuide']['TREND'] else: trend_price = r['product']['priceGuide']['TRENDFOIL'] # Set competitive price for region if undercut_local_market: table_data_local, table_data = self.get_competition( api, product_id, is_foil) if len(table_data_local) > 0: # Undercut if there is local competition lowest_in_country = PyMkmHelper.round_down_to_limit(rounding_limit, PyMkmHelper.calculate_lowest(table_data_local, 4)) new_price = max(rounding_limit, min( trend_price, lowest_in_country - rounding_limit)) else: # No competition in our country, set price a bit higher. new_price = PyMkmHelper.round_up_to_limit( rounding_limit, trend_price * 1.2) else: new_price = PyMkmHelper.round_up_to_limit( rounding_limit, trend_price) if new_price == None: raise ValueError('No price found!') else: return new_price
class TestPyMkmHelperFunctions(unittest.TestCase): def setUp(self): self.helper = PyMkmHelper() def test_calculate_average(self): table = [['Yxskaft', 'SE', 'NM', 1, 1.21], ['Frazze11', 'SE', 'NM', 3, 1.3], ['andli826', 'SE', 'NM', 2, 1.82]] self.assertEqual(self.helper.calculate_average(table, 3, 4), 1.46) def test_calculate_median(self): table = [['Yxskaft', 'SE', 'NM', 1, 1.21], ['Frazze11', 'SE', 'NM', 3, 1.3], ['andli826', 'SE', 'NM', 2, 1.82]] self.assertEqual(self.helper.calculate_median(table, 3, 4), 1.3) self.assertEqual(self.helper.calculate_average(table, 3, 4), 1.46) def test_calculate_lowest(self): table = [['Yxskaft', 'SE', 'NM', 1, 1.21], ['Frazze11', 'SE', 'NM', 3, 1.3], ['andli826', 'SE', 'NM', 2, 1.82]] self.assertEqual(self.helper.calculate_lowest(table, 4), 1.21) def test_round_up_to_limit(self): self.assertEqual(self.helper.round_up_to_limit(0.25, 0.99), 1) self.assertEqual(self.helper.round_up_to_limit(0.25, 0), 0) self.assertEqual(self.helper.round_up_to_limit(0.25, 0.1), 0.25) self.assertEqual(self.helper.round_up_to_limit(0.1, 0.99), 1) self.assertEqual(self.helper.round_up_to_limit(0.01, 0.011), 0.02) self.assertEqual(self.helper.round_up_to_limit(0.01, 1), 1) self.assertEqual(self.helper.round_up_to_limit(1, 0.1), 1) def test_round_down_to_limit(self): self.assertEqual(self.helper.round_down_to_limit(0.25, 0.99), 0.75) self.assertEqual(self.helper.round_down_to_limit(0.25, 1.01), 1) self.assertEqual(self.helper.round_down_to_limit(0.25, 0.1), 0) self.assertEqual(self.helper.round_down_to_limit(0.1, 0.99), 0.9) self.assertEqual(self.helper.round_down_to_limit(0.01, 0.011), 0.01) self.assertEqual(self.helper.round_down_to_limit(0.01, 1), 1) self.assertEqual(self.helper.round_down_to_limit(1, 0.1), 0) @patch('sys.stdout', new_callable=io.StringIO) @patch('builtins.input', side_effect=['y', 'n', 'p', 'n']) def test_prompt_bool(self, mock_input, mock_stdout): self.assertTrue(self.helper.prompt_bool('test_y')) self.assertFalse(self.helper.prompt_bool('test_n')) self.helper.prompt_bool('test_error') self.assertRegex(mock_stdout.getvalue(), r'\nPlease answer with y\/n\n') @patch('builtins.input', side_effect=['y']) def test_prompt_string(self, mock_input): self.assertEqual(self.helper.prompt_string('test'), 'y')
def get_price_for_product(self, product_id, rarity, is_foil, is_playset, language_id=1, undercut_local_market=False, api=None): try: response = api.get_product(product_id) except Exception as err: print('No response from API.') sys.exit(0) else: rounding_limit = self.get_rounding_limit_for_rarity(rarity) if response: if not is_foil: trend_price = response['product']['priceGuide']['TREND'] else: trend_price = response['product']['priceGuide'][ 'TRENDFOIL'] # Set competitive price for region if undercut_local_market and not is_playset: # FIXME: add support for playsets? table_data_local, table_data = self.get_competition( api, product_id, is_foil) if len(table_data_local) > 0: # Undercut if there is local competition lowest_in_country = PyMkmHelper.round_down_to_limit( rounding_limit, PyMkmHelper.calculate_lowest(table_data_local, 4)) new_price = max( rounding_limit, min(trend_price, lowest_in_country - rounding_limit)) else: # No competition in our country, set price a bit higher. new_price = PyMkmHelper.round_up_to_limit( rounding_limit, trend_price * 1.2) else: new_price = PyMkmHelper.round_up_to_limit( rounding_limit, trend_price) if new_price == None: raise ValueError('No price found!') else: if is_playset: new_price = 4 * new_price return new_price else: print('No results.')