def getPlaceType(self, coord: Coord): (dx, dy) = (distance(self.middle, coord.x), distance(self.middle, coord.y)) if dx > self.middle or dy > self.middle or (dx == self.middle and dy == self.middle): return 'EXCLUDED' if dx == self.middle or dy == self.middle or (dx == self.middle - 1 and dy == self.middle - 1): return 'SEA' return 'GROUND'
def grant_coupons(cls, payment, longitude, latitude, accuracy): if not all([longitude, latitude, accuracy]): # 如果没有定到位,则使用商户位置 longitude = payment.merchant.location_lon latitude = payment.merchant.location_lat accuracy = 0 updated = Payment.objects.filter( serial_number=payment.serial_number, status=config.PAYMENT_STATUS.FROZEN, coupon_granted=False).update(coupon_granted=True) if not updated: return [] if accuracy > config.GRANT_COUPON_DISTANCE: # accuracy too low return [] now = timezone.now() now_date = now.date() selected_rules = CouponRule.objects.filter( merchant__location_lon__gte=longitude - metre_to_degree(config.GRANT_COUPON_DISTANCE), merchant__location_lon__lte=longitude + metre_to_degree(config.GRANT_COUPON_DISTANCE), merchant__location_lat__gte=latitude - metre_to_degree(config.GRANT_COUPON_DISTANCE), merchant__location_lat__lte=latitude + metre_to_degree(config.GRANT_COUPON_DISTANCE), merchant__status=config.MERCHANT_STATUS.USING, stock__gt=0, ).exclude(merchant_id=payment.merchant_id).filter( Q(valid_strategy=config.VALID_STRATEGY.EXPIRATION) | Q(end_date__gte=now_date)).order_by('?') result = [] for rule in selected_rules: if len(result) >= 3: return result if distance( rule.merchant.location_lon, rule.merchant.location_lat, longitude, latitude) > config.GRANT_COUPON_DISTANCE: # 前面是初步筛选,这里精确筛选 continue updated = CouponRule.objects.filter( id=rule.id, stock__gt=0).update(stock=F('stock') - 1) if updated: coupon = Coupon.objects.create( rule=rule, client=payment.client, discount=rule.discount, min_charge=rule.min_charge, originator_merchant=payment.merchant, status=config.COUPON_STATUS.NOT_USED) result.append(coupon) else: return result
def _calc_distance(self, cities): """ :type cities: list[] :rtype: float """ if len(cities) > len(self.city_numbers): raise ValueError("Travel is shorter than all the cities available!") cities = map(lambda city_number: cities[city_number], self.city_numbers) total_distance = 0 for i, city in enumerate(cities): if i < len(cities) - 1: total_distance += distance(city, cities[i + 1]) return total_distance
def test_distance2(self): dist = distance(100, 200, 101, 201) assert round(dist * 10) == 1572554
def test_distance1(self): dist = distance(100, 200, 100, 201) assert round(dist * 10) == 1111949
def test_distance_function(self): a = City(1, 9.0, 7.0) b = City(2, 3.0, 2.0) actual_distance = distance(a, b) self.assertAlmostEqual(7.81, actual_distance, places=2)
def test_distance_function_on_negative(self): a = City(1, -3.0, 5.0) b = City(2, 7.0, -1.0) actual_distance = distance(a, b) self.assertAlmostEqual(11.66, actual_distance, places=2)