@@ -111,31 +111,50 @@ async def zen(
111
111
zen_lines = ZEN_OF_PYTHON .splitlines ()
112
112
113
113
# Prioritize checking for an index or slice
114
- match = re .match (r"(-?\d+)(:(-? \d+)?)?" , search_value .split (" " )[0 ])
114
+ match = re .match (r"(?P<index> -?\d++(?!:))|(?P<start>(?:-\d+)|\d*):(?:(?P<end>(?:-\d+)|\d*)(?::(?P<step>(?:- \d+)|\d*) )?)?" , search_value .split (" " )[0 ])
115
115
if match :
116
- upper_bound = len (zen_lines ) - 1
117
- lower_bound = - 1 * len (zen_lines )
118
-
119
- start_index = int (match .group (1 ))
120
-
121
- if not match .group (2 ):
122
- if not (lower_bound <= start_index <= upper_bound ):
123
- raise BadArgument (f"Please provide an index between { lower_bound } and { upper_bound } ." )
124
- embed .title += f" (line { start_index % len (zen_lines )} ):"
125
- embed .description = zen_lines [start_index ]
116
+ if match .group ("index" ):
117
+ index = int (match .group ("index" ))
118
+ if not (- 19 <= index <= 18 ):
119
+ raise BadArgument (f"Please provide an index between { - 19 } and { 18 } ." )
120
+ embed .title += f" (line { index % 19 } ):"
121
+ embed .description = zen_lines [index ]
126
122
await ctx .send (embed = embed )
127
123
return
128
124
129
- end_index = int (match .group (3 )) if match .group (3 ) else len (zen_lines )
130
-
131
- if not ((lower_bound <= start_index <= upper_bound ) and (lower_bound <= end_index <= len (zen_lines ))):
132
- raise BadArgument (f"Please provide valid indices between { lower_bound } and { upper_bound } ." )
133
- if not (start_index % len (zen_lines ) < end_index % (len (zen_lines ) + 1 )):
134
- raise BadArgument ("The start index for the slice must be smaller than the end index." )
135
-
136
- embed .title += f" (lines { start_index % len (zen_lines )} -{ (end_index - 1 )% len (zen_lines )} ):"
137
- embed .description = "\n " .join (zen_lines [start_index :end_index ])
138
- await ctx .send (embed = embed )
125
+ start_index = int (match .group ("start" )) if match .group ("start" ) else None
126
+ end_index = int (match .group ("end" )) if match .group ("end" ) else None
127
+ step_size = int (match .group ("step" )) if match .group ("step" ) else 1
128
+
129
+ if step_size == 0 :
130
+ raise BadArgument (f"Step size must not be 0." )
131
+
132
+ lines = zen_lines [start_index :end_index :step_size ]
133
+ if not lines :
134
+ raise BadArgument (f"Slice returned 0 lines." )
135
+ elif len (lines ) == 1 :
136
+ embed .title += f" (line { zen_lines .index (lines [0 ])} ):"
137
+ embed .description = lines [0 ]
138
+ await ctx .send (embed = embed )
139
+ elif lines == zen_lines :
140
+ embed .title += ", by Tim Peters"
141
+ await ctx .send (embed = embed )
142
+ elif len (lines ) == 19 :
143
+ embed .title += f" (step size { step_size } ):"
144
+ embed .description = "\n " .join (lines )
145
+ await ctx .send (embed = embed )
146
+ else :
147
+ if step_size != 1 :
148
+ step_message = f", step size { step_size } "
149
+ else :
150
+ step_message = ""
151
+ first_position = zen_lines .index (lines [0 ])
152
+ second_position = zen_lines .index (lines [- 1 ])
153
+ if first_position > second_position :
154
+ (first_position , second_position ) = (second_position , first_position )
155
+ embed .title += f" (lines { first_position } -{ second_position } { step_message } ):"
156
+ embed .description = "\n " .join (lines )
157
+ await ctx .send (embed = embed )
139
158
return
140
159
141
160
# Try to handle first exact word due difflib.SequenceMatched may use some other similar word instead
0 commit comments