-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.py
165 lines (135 loc) · 7.5 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import telegram
from data import *
from telegram.ext import Updater
from telegram.ext import CommandHandler
import os
TOKEN = '881647707:AAHJuAV_jyipzKQCJGKnlfKqk21a-q62FVo'
''' Initiates the conversation with the Bot and, by default, creates a graph with d = 1000.'''
def start(bot, update, user_data):
name = update.message.chat.first_name
message = "Hello, " + name + "!"
bot.send_message(chat_id=update.message.chat_id, text=message)
G = CreateGraph_nlogn()
user_data['graph'] = G
''' Prints all the names of all the possible commands and a short explanation to help the user run the bot.'''
def help_(bot, update):
message = 'This Bot answers textually and graphically (with maps) questions related to geometric graphs defined on the stations of the bicing of Barcelona. \n\
It answers the following commands: \n\
/start: initiates a conversation with the Bot. \n\
/authors: writes the name of the authors of the project and their emails. \n\
/graph <distance>: creates a graph with nodes and edges at distance lower than d. By default, d = 1000 \n\
/nodes: prints the numbers of stations at distance lower than d. \n\
/edges: print the number of edges in the graph. \n\
/components: prints the number of connex components in the graph. \n\
/plotgraph: shows an image corresponding to a map, with the corresponding nodes of the graph (in red) and the edges(in blue). \n\
/route origin, destination: shows an image corresponding to the shortest path between the origin and the destination. It also prints the expected time that takes you to the destination. \n\
/distribute <bikes, docks>: prints the route and the number of bikes that a hypothetical vehicle should carry in order to guarantee that every station of the Bicing company in Barcelona has n bicycles and m empty docks.'
bot.send_message(chat_id=update.message.chat_id, text=message)
''' Writes the name of the authors of the project and their emails.'''
def authors(bot, update):
integrant1 = "Joan Vaquer Perelló ([email protected])"
integrant2 = "Míriam Barrabés i Torrella ([email protected])"
bot.send_message(chat_id=update.message.chat_id, text=integrant1)
bot.send_message(chat_id=update.message.chat_id, text=integrant2)
''' If given an argument, creates a graph with nodes and edges at distance lower than the distance given.
If the distance is >= 300, the graph is created in nlog(n) time.
On the contrary, the graph is created in quadratic time.'''
def graph(bot, update, user_data, args):
bot.send_message(chat_id=update.message.chat_id, text="Creating graph")
if not args:
G = CreateGraph_nlogn()
else:
if int(args[0]) >= 300:
G = CreateGraph_nlogn(int(args[0]))
else:
G = CreateGraph_nn(int(args[0]))
bot.send_message(chat_id=update.message.chat_id, text="Graph created!")
user_data['graph'] = G
''' Prints the number of nodes (stations) of the graph.'''
def number_nodes(bot, update, user_data):
n = nodes(user_data['graph'])
bot.send_message(chat_id=update.message.chat_id, text=n)
''' Prints the number of edges of the graph.'''
def number_edges(bot, update, user_data):
e = edges(user_data['graph'])
bot.send_message(chat_id=update.message.chat_id, text=e)
''' Prints the number of connected components of the graph.'''
def connex_components(bot, update, user_data):
c = components(user_data['graph'])
bot.send_message(chat_id=update.message.chat_id, text=c)
''' Shows an image corresponding to a map, with the corresponding nodes (red) and edges(blue).'''
def plotgraph(bot, update, user_data):
try:
path = str(update.message.chat.id) + '.png'
draw_graph(user_data['graph'], path)
bot.send_photo(chat_id=update.message.chat_id, photo=open(path, 'rb'))
os.remove(path)
except:
print("error")
''' Concatenates all the words in one string.'''
def concatenate(args):
paraula = args[0]
n = len(args)
for i in range(1, n):
paraula += ' ' + args[i]
return paraula
''' Given an hour, it decomposes it in hours, minutes and seconds, and returns these values in a string.'''
def hours_to_string(hour):
seconds = hour*3600
h = int(seconds//3600)
m = int((seconds % 3600)//60)
s = int((seconds % 3600) % 60)
time = str(h) + " hours, " + str(m) + " minutes and " + str(s) + " seconds"
return time
''' Given a route, shows an image corresponding to the shortest path between the origin and the destination.
It also prints the expected time until the user arrives at the destination.'''
def route(bot, update, user_data, args):
path1 = str(update.message.chat.id) + 'jm.png'
p = concatenate(args)
a = ShortestPath(user_data['graph'], p, path1)
if a is not "Adress not found":
bot.send_message(chat_id=update.message.chat_id,
text="Searching for the fastest path...")
bot.send_photo(chat_id=update.message.chat_id, photo=open(path1, 'rb'))
b = hours_to_string(a)
bot.send_message(chat_id=update.message.chat_id, text=b)
os.remove(path1)
else:
bot.send_message(chat_id=update.message.chat_id, text=a)
''' Prints the route and the number of bikes that a hypothetical vehicle should carry to guarantee that every station
of the Bicing company in Barcelona has 'n' bicycles and 'm' empty docks.'''
def distribute(bot, update, user_data, args):
requiredBikes = int(args[0])
requiredDocks = int(args[1])
totalkm, maxcost, err = distribute(
user_data['graph'], requiredBikes, requiredDocks)
if err and totalkm == 1:
bot.send_message(chat_id=update.message.chat_id,
text="No solution could be found")
elif err and totalkm == 2:
bot.send_message(chat_id=update.message.chat_id,
text="Fatal Error: Incorrect graph model.")
else:
message1 = "The total cost of transferring bikes is:" + \
str(int((totalkm))/1000) + " km."
message2 = "The move of maxmimum cost is:" + \
str(int((maxcost[0]*1000))/1000) + " km*bikes, between the stations " + \
str(maxcost[1]) + " and " + str(maxcost[2])
bot.send_message(chat_id=update.message.chat_id, text=message1)
bot.send_message(chat_id=update.message.chat_id, text=message2)
''' Declares a constant with the access token that reads from token.txt.'''
updater = Updater(token=TOKEN)
dispatcher = updater.dispatcher
''' As soon as the bot receives a message with some of the commands below, it will execute the corresponding function.'''
dispatcher.add_handler(CommandHandler('start', start, pass_user_data=True))
dispatcher.add_handler(CommandHandler('help', help_))
dispatcher.add_handler(CommandHandler('authors', authors))
dispatcher.add_handler(CommandHandler('graph', graph, pass_user_data=True, pass_args=True))
dispatcher.add_handler(CommandHandler('plotgraph', plotgraph, pass_user_data=True))
dispatcher.add_handler(CommandHandler('nodes', number_nodes, pass_user_data=True))
dispatcher.add_handler(CommandHandler('edges', number_edges, pass_user_data=True))
dispatcher.add_handler(CommandHandler('components', connex_components, pass_user_data=True))
dispatcher.add_handler(CommandHandler('route', route, pass_user_data=True, pass_args=True))
dispatcher.add_handler(CommandHandler('distribute', distribute, pass_user_data=True, pass_args=True))
''' Starts up the bot.'''
updater.start_polling()