Advertisement
IamFraise

UBER

Jan 15th, 2025 (edited)
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.32 KB | None | 0 0
  1. import random
  2. import math
  3. from dataclasses import field, dataclass
  4. from typing import List
  5.  
  6. City_Fares = { # Tarifa mínima para cada cidade da simulação
  7.     "São José dos Campos": 5,
  8.     "Jacareí" : 4,
  9.     "Mogi das Cruzes": 4.5,
  10.     "Caçapava": 3.5,
  11.     "Guararema": 3.0,
  12.     "Santa Branca": 2.75,
  13.     "Santa Preta": 2.5,
  14.     "Urbanova": 3.25,
  15.     "Jambeiro": 2.25,
  16.     "Desaparecida": 3.75
  17. }
  18.  
  19. CarList1 = ["Hyundai HB20", "Kia Cerato", "Chevrolet Onix", "Fiat Mobi", "Fiat Uno", "Nissan Leaf"]
  20. CarList2 = ["Land Rover Defender", "Hyundai Santa Fe", "Toyota Prius", "Jaguar XF", "Mercedes E-Class", "Lexus GS", "Mercedes GL", "Volvo XC60"]
  21. CarList3 = ["Toyota AE86 Trueno", "Honda NSX", "Fiat Uno Mille", "Mini Cooper", "Pagani Huayra", "Porsche 918 Spyder", "Ferrari F40"]
  22.  
  23. Car_List = { # Carros e seus valores associados. O valor ao lado do nome do carro define quais serviços ele pode fazer
  24.     # Cada serviço tem uma chave prima associada (UberX = 2) e se o valor associado a um carro for divisível por essa
  25.     # chave prima, o carro pode prestar esse serviço
  26.     "Hyundai HB20": 2,
  27.     "Kia Cerato": 2,
  28.     "Chevrolet Onix": 2,
  29.     "Fiat Mobi": 2,
  30.     "Fiat Uno": 2,
  31.     "Nissan Leaf": 2,
  32.     "Land Rover Defender": 6,
  33.     "Hyundai Santa Fe": 6,
  34.     "Toyota Prius": 6,
  35.     "Jaguar XF": 10,
  36.     "Mercedes E-Class": 10,
  37.     "Lexus GS": 10,
  38.     "Mercedes GL": 30,
  39.     "Volvo XC60": 30,
  40.     "Toyota AE86 Trueno": 14,
  41.     "Honda NSX": 14,
  42.     "Fiat Uno Mille": 14,
  43.     "Mini Cooper": 22,
  44.     "Pagani Huayra": 22,
  45.     "Porsche 918 Spyder": 22,
  46.     "Ferrari F40": 154
  47. }
  48.  
  49. Uber_Types = {
  50.     2: "UberX",
  51.     3: "UberXL",
  52.     5: "Uber black",
  53.     7: "Uber vintage",
  54.     11: "Uber lux"
  55. }
  56.  
  57. def UberChooser(): # Essa função decide qual será o tipo da viagem
  58.     TypeVar = random.randrange(1,100,1)
  59.     if TypeVar <= 50:
  60.         return 2 # UberX
  61.     if TypeVar <= 70:
  62.         return 3 # UberXL
  63.     if TypeVar <= 90:
  64.         return 5 # Uber Black
  65.     if TypeVar <= 95:
  66.         return 7 # Uber Vintage (inventado)
  67.  
  68.     return 11 # Uber Lux
  69.  
  70. def FareFromType(Rtype): # Muda valor da corrida dependendo do tipo solicitado
  71.     if Rtype == 2:
  72.         return 1 # Taxa pra UberX
  73.     if Rtype == 3:
  74.         return 1.2 # Taxa pra UberXL
  75.     if Rtype == 5:
  76.         return 1.3 # Taxa pra Uber black
  77.     if Rtype == 7:
  78.         return 1.5 # Taxa pra Uber vintage
  79.  
  80.     return 2 # Taxa pra Uber lux
  81.  
  82. def CalculateTip(aride): # Calcula a gorjeta dependendo do valor da corrida
  83.     Tip = random.randrange(1,1000,1)
  84.     if Tip <= 500:
  85.         return 0 # 50% de chance de não ter gorjeta
  86.     if Tip <= 800:
  87.         return aride.price / 20 # 30% de chance de ter gorjeta equivalente a 5% da corrida
  88.     if Tip <= 900:
  89.         return aride.price / 10 # 10% de chance de ter gorjeta equivalente a 10% da corrida
  90.     if Tip <= 950:
  91.         return aride.price / 5 # 5% de chance de ter gorjeta equivalente a 20% da corrida
  92.     if Tip <= 999:
  93.         return aride.price / 4  # 4.9% de chance de ter gorjeta equivalente a 25% da corrida
  94.  
  95.     return aride.price # 0.1% de chance de ter gorjeta equivalente a 100% da corrida... boa sorte!
  96.  
  97. def ChooseCar(owner): # Essa função dá um carro aleatório para um motorista
  98.     if owner.name == "Fabrício Müller":
  99.         return "Toyota AE86 Trueno"
  100.     if owner.name == "Sofia Almeida":
  101.         return "Mini Cooper"
  102.     if owner.name == "Gabriel Garcia":
  103.         return "Chevrolet Onix"
  104.  
  105.     CarChoice = random.randrange(1, 100, 1)
  106.     if CarChoice <= 65:
  107.         return random.choice(CarList1) # Escolhe um carro da lista básica
  108.  
  109.     if CarChoice <= 95:
  110.         return random.choice(CarList2) # Escolhe um carro da lista avançada
  111.  
  112.     return random.choice(CarList3) # Escolhe um carro da lista premium
  113.  
  114. def GetNewCar(owner): # Função dá um novo carro para um motorista aleatório
  115.     aux = False
  116.     loops = 0
  117.     ncar = ""
  118.     while not aux and loops <= 100:
  119.         CarChoice = random.randrange(1, 100, 1)
  120.         if CarChoice <= 65:
  121.             ncar = random.choice(CarList1)
  122.         elif CarChoice <= 95:
  123.             ncar = random.choice(CarList2)
  124.         else:
  125.             ncar = random.choice(CarList3)
  126.         if ncar not in owner.cars:
  127.             owner.cars.append(ncar)
  128.             print(owner.name,"just got a", ncar)
  129.             aux = True
  130.         else:
  131.             loops = loops + 1
  132.  
  133.  
  134.     return owner
  135.  
  136.  
  137. # Lista que contém os primeiros nomes possíves para passageiros e motoristas
  138. Fnames = ["Otávio", "Fabrício", "Sofia", "Gabriel", "Fábio", "Felipe", "Vanessa", "Carol", "Iasmin", "Cláudia", "Henrique", "Thadeu", "Sasha", "Sarah", "Marcelo", "Sushi", "Raul"]
  139.  
  140. # Lista que contém os últimos nomes possíveis para passageiros e motoristas
  141. Lnames = ["Lemos", "Müller", "Almeida", "Garcia", "Cappabianco", "Marcondes", "Cesarini", "Andrade", "Campos", "Tanaka", "Senne", "Oliveira", "Rodela", "Tomita", "Gama", "Benito"]
  142.  
  143. @dataclass
  144. class Position:
  145.     Xpos: float
  146.     Ypos: float
  147.  
  148. def CityFinder(pos): # Essa função descobre em qual cidade qualquer posição específica é localizada
  149.     xpos = pos.Xpos
  150.     ypos = pos.Ypos
  151.     if xpos > 170 and ypos > 170:
  152.         return "Caçapava"
  153.     if 0 <= xpos <= 170 and 0 <= ypos <= 190:
  154.         return "São José dos Campos"
  155.     if -50 < xpos < 0 and 150 < ypos < 190:
  156.         return "Urbanova"
  157.     if -80 <= xpos <= 0 and -50 <= ypos <= 150:
  158.         return "Jacareí"
  159.     if 0 < xpos < 30 and -70 < ypos < -50:
  160.         return "Santa Branca"
  161.     if -30 < xpos < 0 and -70 < ypos < -50:
  162.         return "Santa Preta"
  163.     if -80 < xpos < -30 and -80 < ypos < -50:
  164.         return "Guararema"
  165.     if 150 < xpos < 170 and -70 < ypos < -50:
  166.         return "Jambeiro"
  167.     if xpos > 170 and 0 < ypos < 170:
  168.         return "Desaparecida"
  169.     if -200 < xpos < -80 and -100 < ypos < 0:
  170.         return "Mogi das Cruzes"
  171.     return "???"
  172.  
  173. def IsInCity(pos): # Essa função descobre se uma posição específica está ou não em uma cidade
  174.     xpos = pos.Xpos
  175.     ypos = pos.Ypos
  176.     if xpos > 170 and ypos > 170:
  177.         return True
  178.     if 0 <= xpos <= 170 and 0 <= ypos <= 190:
  179.         return True
  180.     if -50 < xpos < 0 and 150 < ypos < 190:
  181.         return True
  182.     if -80 <= xpos <= 0 and -50 <= ypos <= 150:
  183.         return True
  184.     if 0 < xpos < 30 and -70 < ypos < -50:
  185.         return True
  186.     if -30 < xpos < 0 and -70 < ypos < -50:
  187.         return True
  188.     if -80 < xpos < -30 and -80 < ypos < -50:
  189.         return True
  190.     if 150 < xpos < 170 and -70 < ypos < -50:
  191.         return True
  192.     if xpos > 170 and 0 < ypos < 170:
  193.         return True
  194.     if -200 < xpos < -80 and -100 < ypos < 0:
  195.         return True
  196.     return False
  197.  
  198. def FindDistance(pos1, pos2): # Calcula a distância mínima entre duas posições
  199.     x1 = pos1.Xpos
  200.     y1 = pos1.Ypos
  201.     x2 = pos2.Xpos
  202.     y2 = pos2.Ypos
  203.     varX = x1 - x2
  204.     if 0 > varX:
  205.         varX = varX * -1
  206.     varY = y1 - y2
  207.     if 0 > varY:
  208.         varY = varY * -1
  209.     x1 = math.sqrt(varX * varX + varY * varY)
  210.     return x1
  211.  
  212. def MakeBoostZone():
  213.     aux = False
  214.     while not aux:
  215.         pos = Position(random.uniform(-200, 200), random.uniform(-100, 200))
  216.         aux = IsInCity(pos)
  217.     return pos
  218.  
  219. @dataclass
  220. class Driver:
  221.     name: str
  222.     position: Position
  223.     cars: List[str] = field(default_factory=list) # Lista de carros, usada para definir carro atual
  224.     CurrCar: str = ""
  225.     streak: int = 0 # Sequencia de corridas em um dia do motorista
  226.     city: str = ""
  227.  
  228.     def __str__(self):
  229.         if self.streak == 0:
  230.             return f"{self.name} is in {self.city} and is driving a {self.CurrCar}"
  231.  
  232.         return f"{self.name} is in {self.city}, is driving a {self.CurrCar} and has a streak of {self.streak} rides"
  233.  
  234.     def FindCity(self):
  235.         return CityFinder(self.position)
  236.  
  237.     def CalculateEarnings(self, ridecost, ridetip):
  238.         tax = 25 # Taxa da Uber inicia como 25%
  239.         if 0 <= self.streak <= 5:
  240.             tax = tax - self.streak # Diminui a taxa da Uber de acordo com a sequência de corridas (limíte em 5 corridas)
  241.         elif self.streak > 5:
  242.             tax = 20
  243.         return ridecost - (tax / 100 * ridecost) + ridetip
  244.  
  245.  
  246.  
  247. @dataclass
  248. class Passenger:
  249.     name: str
  250.     position: Position
  251.     city: str = ""
  252.  
  253.     def FindCity(self):
  254.         return CityFinder(self.position)
  255.  
  256.     def __str__(self):
  257.         return f"{self.name} is currently in {self.city}"
  258.  
  259. def PrintRide(aride, tip, earnings, fboost, rtype):
  260.     if not fboost:
  261.         print("The driver was " + aride.driver.name + " the passenger was " + aride.passenger.name + ", the destination was " + CityFinder(aride.destination) + ", the price for the " + str(Uber_Types.get(rtype)) + " was " + str(aride.price) + ", there was a tip of " + str(tip) + " and the driver earned " + str(earnings))
  262.     else:
  263.         print("The driver was " + aride.driver.name + " the passenger was " + aride.passenger.name + ", the destination was " + CityFinder(aride.destination) + ", the price for the " + str(Uber_Types.get(rtype)) + " was a boosted " + str(aride.price) + ", there was a tip of " + str(tip) + " and the driver earned " + str(earnings))
  264.     return
  265.  
  266. @dataclass
  267. class Ride:
  268.     driver: Driver
  269.     passenger : Passenger
  270.     destination: Position
  271.     price: float = 0.0
  272.     boost: bool = False
  273.     type: float = 1.0
  274.  
  275.     def __str__(self):
  276.         return f"The driver was {self.driver.name} and the passenger was {self.passenger.name}, the destination was {CityFinder(self.destination)} and the price was {self.price}"
  277.  
  278.     def CalcPrice(self):
  279.         # Distância entre motorista e passageiro e entre passageiro e destino
  280.         dist = FindDistance(self.driver.position, self.passenger.position) + FindDistance(self.passenger.position, self.destination)
  281.         # Calcula a taxa base usando a cidade do passageiro e cidade destino
  282.         bfare = (City_Fares.get(self.passenger.city) + City_Fares.get(CityFinder(self.destination))) / 2
  283.         # Calcula o tempo baseado na distância total e aleatoriedade
  284.         rideTime = random.uniform(dist - dist / 2, dist + dist / 2) / 5
  285.         # Faz o calculo do preço da corrida usando a tarifa base, a distância, a cidade e o tempo
  286.         bfare = bfare + dist * (0.10 + bfare / 20) + (rideTime * 0.10)
  287.         # Aumenta o preço se a corrida estiver em uma zona booster
  288.         if self.boost is True:
  289.             bfare = bfare * 1.3
  290.         # Multiplica por um valor que depende do tipo da corrida
  291.         bfare = bfare * self.type
  292.  
  293.         return bfare
  294.  
  295. opt = 0
  296. day = 1
  297. boolAux = False
  298. position = 0
  299. Dlist = []
  300. Plist = []
  301. booster = MakeBoostZone()
  302. while opt != 8:
  303.     print("Welcome to Uber simulator! We are currently in day", day, "of the simulation!\nPick an option :\n1) Add driver\n2) Add passenger\n3) Make Uber ride\n4) Give car to driver\n5) Go to next day\n6) Print drivers\n7) Print passengers\n8) Exit")
  304.     opt = int(input())
  305.     if opt == 1: # Cria um novo motorista
  306.         if random.randrange(1, 500,1) == 123:
  307.             dname = "Passos Dias Aguiar"
  308.         else:
  309.             dname = (random.choice(Fnames) + " " + random.choice(Lnames))
  310.         boolAux = False
  311.         while not boolAux:
  312.             position = Position(random.uniform(-200 ,200),random.uniform(-100,200))
  313.             boolAux = IsInCity(position)
  314.         driver = Driver(dname, position)
  315.         driver.city = driver.FindCity()
  316.         driver.cars.append(ChooseCar(driver))
  317.         driver.CurrCar = random.choice(driver.cars)
  318.         Dlist.append(driver)
  319.         print(driver)
  320.     if opt == 2: # Cria um novo passageiro
  321.         pname = (random.choice(Fnames) + " " + random.choice(Lnames))
  322.         boolAux = False
  323.         while not boolAux:
  324.             position = Position(random.uniform(-200 ,200),random.uniform(-100,200))
  325.             boolAux = IsInCity(position)
  326.         passenger = Passenger(pname, position)
  327.         passenger.city = passenger.FindCity()
  328.         Plist.append(passenger)
  329.         print(passenger)
  330.     if opt == 3: # Faz uma corrida com um motorista e um passageiro aleatório
  331.         boolAux = False
  332.         while not boolAux:
  333.             random.shuffle(Plist)
  334.             passenger = Plist.pop() # Sorteia um passageiro para a corrida
  335.             random.shuffle(Dlist)
  336.             driver = Dlist.pop() # Sorteia um motorista para a corrida
  337.             RideType = UberChooser() # Escolhe o tipo de Uber desejado pra viagem
  338.             if Car_List.get(driver.CurrCar) % RideType == 0: # Verifica se o motorista pode efetuar o tipo desejado de viagem
  339.                 boolAux = True
  340.             else:
  341.                 Plist.append(passenger)
  342.                 Dlist.append(driver)
  343.  
  344.         boolAux = False
  345.         while not boolAux: # Pega um destino para a corrida
  346.             position = Position(random.uniform(-200 ,200),random.uniform(-100,200))
  347.             boolAux = IsInCity(position)
  348.         ride = Ride(driver, passenger, position)
  349.         if FindDistance(passenger.position, booster) <= 30 and CityFinder(booster) == passenger.city:
  350.             ride.boost = True
  351.         ride.type = FareFromType(RideType) # Muda o valor da taxa dependendo do tipo de Uber solicitado
  352.         ride.price = ride.CalcPrice() # Calcula o preço da corrida
  353.         tip = CalculateTip(ride) # Calcula a gorjeta
  354.         earnings = driver.CalculateEarnings(ride.price, tip)
  355.         PrintRide(ride, tip, earnings, ride.boost, RideType)
  356.         passenger.position = position
  357.         passenger.city = passenger.FindCity()
  358.         driver.position = position
  359.         driver.city = driver.FindCity()
  360.         driver.streak = driver.streak + 1
  361.         Dlist.append(driver)
  362.         Plist.append(passenger)
  363.     if opt == 4: # Dá um carro novo para um motorista
  364.         random.shuffle(Dlist)
  365.         driver = Dlist.pop()
  366.         driver = GetNewCar(driver)
  367.         Dlist.append(driver)
  368.  
  369.  
  370.     if opt == 5:
  371.         print("Day", day,"is over and streak bonuses were reset...")
  372.         booster = MakeBoostZone()
  373.         print("A booster zone currently exists in part of", CityFinder(booster))
  374.         day = day + 1
  375.         for drivers in Dlist:
  376.             drivers.streak = 0
  377.             drivers.CurrCar = random.choice(drivers.cars)
  378.  
  379.     if opt == 6:
  380.         for drivers in Dlist:
  381.             print(drivers)
  382.         print()
  383.  
  384.     if opt == 7:
  385.         for passengers in Plist:
  386.             print(passengers)
  387.         print()
  388.    
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement