0

I'm having some trouble figuring this problem out. I have a function that has random.randint(alpha_low,alpha_high). alpha_low and alpha_high are letters that got turned into numbers values using the function ord. I then turn them back by using the function chr so that I get a random letter, and append it to final_list. The problem is that I want half of the list in caps, and half in lowercase. But right now, for some reason, my code is not printing half half, although I specified that I want half of it to remain the same, and half to be .upper().

import random
def alpha_list(num_values, alpha_low, alpha_high):
        
    final_list = []
    
    for letter in range(num_values):
        rando = (chr(random.randint(alpha_low, alpha_high)))
        final_list.append(rando)

    for i in range(len(final_list)):
        if final_list[i] > final_list[int((len(final_list)/2)-1)]:
            final_list[i] = final_list[i].upper()
        else:
            pass

    return final_list

user_input_number = eval(input('please type an EVEN amount of letters you want: '))

user_input_first_letter = ord(input('please type the first letter of the limits(lower case): '))

user_input_last_letter = ord(input('please type the last letter of the limits(lower case): '))

print(alpha_list(user_input_number, user_input_first_letter, user_input_last_letter))

I have tried to split the list into 2 lists, and uppercase that list, then combine the lists again, but I feel like that isn't the best way.

Stefan
  • 1,697
  • 15
  • 31
  • 1
    You shouldn't `eval` unsanitized user input unless you want bad things to happen. – flakes Sep 24 '20 at 14:56
  • To follow up on flakes comment, ,take a look at this post "Asking the user for input until they give a valid response" at https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response – itprorh66 Sep 24 '20 at 15:29

5 Answers5

1

You are comparing the letters inside the final_list. You need to compare the index to set half of the letters to uppercase.

Change:

if final_list[i] > final_list[int((len(final_list)/2)-1)]:

to:

if i > len(final_list)/2 - 1:
Saurus
  • 46
  • 4
1

The ASCII values of A through Z are 65 through 90. To get lowercase, you would add 32 to that value.

You can use those initial values (65 through 90) as bounds to determine the letter, and add 32 halfway through the length of your list:

#!/usr/bin/env python3

import random

def build_list(length):
    l = [''] * length
    for i in range(length):
        uc = 32 if i >= length // 2 else 0
        l[i] = chr(random.randint(65, 90) + uc)
    return l

print(build_list(10)) # ['L', 'M', 'Q', 'U', 'H', 'w', 'x', 'o', 'j', 'u']

Adjust your letter bounds, as needed.

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
1
final_list = [item.upper() if idx > len(final_list) else item for idx, item in enumerate(final_list)]

Here we iterating over list again but using enumerate gives index of each element which we can use to construct new list by a condition based on index.

A more neat way using map:

final_list[len(final_list//2):] = list(map(str.upper, final_list[len(final_list//2):]))

Here we get only half of the list and apply str.upper to each element in that half and assign new half to old half.

Kerem Zaman
  • 529
  • 1
  • 5
  • 18
1

Well you could a single for loop to get it done. Try this and let me know if this works for you or you need any explanation for the same.

Code:

import random
from typing import List


def alpha_list(letters: int,
               start: int,
               stop: int,
               randomize: bool = True) -> List[str]:
  """
  Return list of evenly* distributed characters with mixed cases.

  Args:
    letters: Maximum number of characters required in the list.
    start: Starting ordinal range.
    stop: Stopping ordinal range.
    randomize: Boolean to return random sequence.

  Returns:
    List of characters split in upper and lower cases.
  """
  chars = []

  for idx in range(letters):
    temp = (chr(random.randint(start, stop)))
    chars.append(temp.upper() if idx % 2 else temp)

  if randomize:
    random.shuffle(chars)

  return chars


# Usage:
number = int(input("Please enter even amount of characters you want: "))
first = ord(input("Please type the first character of the limits in lowercase "
                  "[ex: a]: "))
last = ord(input("Please type the last character of the limits in lowercase "
                 "[ex: z]: "))

print(alpha_list(number, first, last))

Output:

>>> Please enter even amount of characters you want: 10
>>> Please type the first character of the limits in lowercase [ex: a]: a
>>> Please type the last character of the limits in lowercase [ex: z]: z
['r', 'w', 'r', 'i', 'z', 'U', 'F', 'Z', 'H', 'F']
XAMES3
  • 147
  • 1
  • 6
1

Taking in the cautions about eval of user input, the problem you are having is related to the code:

for i in range(len(final_list)):
        if final_list[i] > final_list[int((len(final_list)/2)-1)]:
            final_list[i] = final_list[i].upper()
        else:
            pass

Since, final_list already contains all lower case letters, you simply need to make the last half of the list upper case. The following statement accomplishes this task:

final_list = final_list[0:len(final_list)//2] + 
              [x in final_list[len(final_list)//2:] x.upper()]
itprorh66
  • 3,110
  • 4
  • 9
  • 21