def test_i18n(): three_seconds = dt.timedelta(seconds=3) one_min_three_seconds = dt.timedelta(milliseconds=67_000) assert humanize.naturaltime(three_seconds) == "3 seconds ago" assert humanize.ordinal(5) == "5th" assert humanize.precisedelta( one_min_three_seconds) == "1 minute and 7 seconds" try: humanize.i18n.activate("ru_RU") assert humanize.naturaltime(three_seconds) == "3 секунды назад" assert humanize.ordinal(5) == "5ый" assert humanize.precisedelta( one_min_three_seconds) == "1 минута и 7 секунд" except FileNotFoundError: pytest.skip( "Generate .mo with scripts/generate-translation-binaries.sh") finally: humanize.i18n.deactivate() assert humanize.naturaltime(three_seconds) == "3 seconds ago" assert humanize.ordinal(5) == "5th" assert humanize.precisedelta( one_min_three_seconds) == "1 minute and 7 seconds"
def test_i18n(): three_seconds = dt.timedelta(seconds=3) assert humanize.naturaltime(three_seconds) == "3 seconds ago" assert humanize.ordinal(5) == "5th" try: humanize.i18n.activate("ru_RU") assert humanize.naturaltime(three_seconds) == "3 секунды назад" assert humanize.ordinal(5) == "5ый" finally: humanize.i18n.deactivate() assert humanize.naturaltime(three_seconds) == "3 seconds ago" assert humanize.ordinal(5) == "5th"
def verify_code(book, first_letter, spacing, length, index=0): entire_text = hebrew_letters_only(''.join(book['text'][0])) print entire_text first_index = [m.start() for m in re.finditer(first_letter,entire_text)][index] print "Starting from the %s %s every %s letters in book %s:" % (humanize.ordinal(index+1), first_letter, spacing, book['name']) #print "context: %s" % entire_text[first_index: first_index + (spacing * length)] print "%s: %s" % (first_index, entire_text[first_index: first_index + (spacing * length): spacing])
async def points(ctx: commands.Context): if not scoreboard.has_data_for_guild(ctx.guild): await ctx.channel.send("Nobody has said anything yet!") return top = scoreboard.get_top(5, ctx=ctx) asker_points = scoreboard.get_points_for_member(ctx.author) asker_position = scoreboard.get_points_position(asker_points, ctx=ctx) ordinal = humanize.ordinal(asker_position + 1) if top: top_msg = fence( "\n".join( f"{i+1}. {member.display_name}: {humanize.intcomma(points)} points" for i, (member, points) in enumerate(top) ) ) else: top_msg = "Nobody has any points yet..." asker_points_msg = f"<@{ctx.author.id}> you have {humanize.intcomma(asker_points)} points, " if asker_position == 0: asker_position_msg = f"putting you at the top! :tada:" elif asker_points == 0: asker_position_msg = f"get chatting!" else: asker_position_msg = f"putting you in {ordinal} position." await ctx.channel.send(f"Top 5:\n{top_msg}\n{asker_points_msg}{asker_position_msg}")
def test_ordinal_genders(locale, number, gender, expected_result): try: humanize.i18n.activate(locale) except FileNotFoundError: pytest.skip( "Generate .mo with scripts/generate-translation-binaries.sh") else: assert humanize.ordinal(number, gender=gender) == expected_result finally: humanize.i18n.deactivate()
def test_i18n(): three_seconds = dt.timedelta(seconds=3) one_min_three_seconds = dt.timedelta(milliseconds=67_000) assert humanize.naturaltime(three_seconds) == "3 seconds ago" assert humanize.ordinal(5) == "5th" assert humanize.precisedelta(one_min_three_seconds) == "1 minute and 7 seconds" try: humanize.i18n.activate("ru_RU") assert humanize.naturaltime(three_seconds) == "3 секунды назад" assert humanize.ordinal(5) == "5ый" assert humanize.precisedelta(one_min_three_seconds) == "1 минута и 7 секунд" finally: humanize.i18n.deactivate() assert humanize.naturaltime(three_seconds) == "3 seconds ago" assert humanize.ordinal(5) == "5th" assert humanize.precisedelta(one_min_three_seconds) == "1 minute and 7 seconds"
def from_dict(cls, matrix): # Usually from_dict is called as part of parse_yaml so error messages # somewhat assume the input is actually yaml def _raise(msg): raise UserError(f'{msg}\n\n{cls._matrix_example_msg}') # Basic validation if not isinstance(matrix, dict): _raise('The matrix should be a dictionary.\n\nGiven matrix: {!r}'. format(matrix)) if 'name' not in matrix: _raise('Please provide a name for the matrix.') if 'data' not in matrix: _raise('Please provide the data of the matrix.') data = matrix['data'] if not isinstance(data, list): _raise('data should be a list.\n\nGiven data: {!r}'.format(data)) if not data: _raise('data must not be empty.\n\nGiven data: {!r}'.format(data)) # Rows should be lists for i, row in enumerate(data, 1): if not isinstance(row, list): _raise('The {} row is not a list. Perhaps you forgot to wrap ' 'the row in []?\n\nGiven row: {!r}'.format( humanize.ordinal(i), row)) # Column count should be consistent across rows column_count = len(data[0]) for i, row in enumerate(data[1:], 2): if len(row) != column_count: difference = 'more' if len(row) > column_count else 'less' _raise( 'The {} row has {} columns than previous rows. All rows ' 'should have the same length.\n\nGiven row: {!r}'.format( humanize.ordinal(i), difference, row)) # dtype=object to preserve the type, else the whole lot can become str # for example data = np.array(data, dtype=object) cls._warn_if_unexpected_type(data) return cls._from_array(matrix['name'], data)
def parse_date(string): # Parse schedule string pdt_obj, status = pdt.Calendar().parse( string) # Turn any human-written string into a pdt object datetime_obj = datetime( *pdt_obj[:6]) # Turn the object into a datetime object day = humanize.naturalday(datetime_obj, "%A").capitalize() # 'Tomorrow' or 'Wednesday' if day not in ["Today", "Tomorrow"]: # Set day to be of the format "Wednesday 24th Feb" # For full months, swap "%b" for "%B" day = " ".join([ day, humanize.ordinal(datetime_obj.day), datetime_obj.strftime("%b") ]) time = datetime_obj.strftime(" at %H%M") return datetime_obj, day + time
def parse_recurrence(self): events_result = {} with open('lib/drone_hangar/static/google/recurrence.json', 'r') as f: events_result = json.loads(f.read()) recurrence = { } # Keys should be human-readable recurrence patterns. This is going to be displayed on the Events page in HTML. recurrence_lists = { 'annual': [], 'monthly': [], 'weekly': [], 'daily': [] } for event in events_result: rule = { 'raw': event['recurrence'][0][6:].split(';'), # TODO: If I ever upgrade to 3.9, I can change the awkward slicing syntax to `removeprefix('RRULE:')`. 'freq': '', 'byday': [], 'bymonth': [], 'bymonthday': [], 'bysetpos': [], 'count': 0, 'until': '', 'interval': 0 } # For each event, generate a tuple with a human-readable description of the recurrence rule, then use dict() to compile them into a dictionary. if "FREQ=YEARLY" in rule['raw']: rule['freq'] = 'annual' elif "FREQ=MONTHLY" in rule['raw']: rule['freq'] = 'monthly' elif "FREQ=WEEKLY" in rule['raw']: rule['freq'] = 'weekly' elif "FREQ=DAILY" in rule['raw']: rule['freq'] = 'daily' else: logging.debug( '> > > No RRULE repetition type found. Jumping to next event.' ) # RRULE syntax is keyword-based, so we shouldn't care about position here. Just iterate through the list and assign variables as we find them. rule_text = '' for prop in rule['raw']: prop = prop.partition('=') if prop[0] == 'BYDAY': rule['byday'] = prop[2].split(',') elif prop[0] == 'BYMONTH': rule['bymonth'] = prop[2].split(',') elif prop[0] == 'BYMONTHDAY': rule['bymonthday'] = prop[2].split(',') elif prop[0] == 'BYSETPOS': rule['bysetpos'] = prop[2].split(',') elif prop[0] == 'COUNT': rule['count'] = prop[2] elif prop[0] == 'UNTIL': rule['until'] = prop[2] elif prop[0] == 'INTERVAL': rule['interval'] = prop[2] intervals = { 0: '', 1: '', 2: 'Every other', 3: 'Every third', 4: 'Every fourth', 5: 'Every fifth' } # Day codes can start with the string or with a positive or negative number. The day strings are predictable, so it's easy to find them with the range [-2:]. days = { 'SU': 'Sunday', 'MO': 'Monday', 'TU': 'Tuesday', 'WE': 'Wednesday', 'TH': 'Thursday', 'FR': 'Friday', 'SA': 'Saturday' } pos = { '-3': '3rd to last', '-2': '2nd to last', '-1': 'Last', '': '', **{ # We can save ourselves from having to type numbers. f'{n}': humanize.ordinal(n) for n in range(1, 31) } } months = { 1: 'January', 2: 'February', 3: 'March', 4: 'April', 5: 'May', 6: 'June', 7: 'July', 8: 'August', 9: 'September', 10: 'October', 11: 'November', 12: 'December' } interval_text = intervals[rule['interval']] day_list = [f'{pos[d[:-2]]} {days[d[-2:]]}' for d in rule['byday']] day_text = ", ".join(day_list[:-2] + [", and ".join(day_list[-2:])]) month_list = [months[m] for m in rule['bymonth']] month_text = ", ".join(month_list[:-2] + [", and ".join(month_list[-2:])]) setpos_text = '' # TODO: BYSETPOS is kind of terrible. It's unlikely to actually come up, since it's used for some weird scheduling patterns, so I might be able to get away with half-assing it. if rule['freq'] == 'annual': # Should usually just be the month. if interval_text: interval_text = f'{interval_text} year:' rule_text = f'{interval_text} {month_text}' elif rule['freq'] == 'monthly': # Should usually just be the day with either an interval or a position notifier. if interval_text: interval_text = f'{interval_text} month:' rule_text = f'{interval_text} {day_text}' elif rule['freq'] == 'weekly': # Day position shouldn't be a thing here. if interval_text: interval_text = f'{interval_text} week:' rule_text = f'{interval_text} {day_text}' recurrence_lists[rule['freq']].append((rule_text, event['id'])) for key, events in recurrence_lists.items(): recurrence.update({key: defaultdict(list)}) for entry in events: recurrence[key][entry[0]].append(entry[1]) logging.debug(f'{entry[0]} in {key} set to {entry[1]}') recurrence = {k: dict(v) for k, v in recurrence.items()} return recurrence
def test_ordinal(test_input, expected): assert humanize.ordinal(test_input) == expected