Python, split user input twice. At pair and space - python

I'm a Python beginner and would like to know how to split a user input at pair and at space and add it to a list.
E.g:
user = input('A1 KW')
user.split(" " ) # split on space
Then I'd like to print the input on index 0 what should be A1 and also print the alphabet and number/alphabet of each index.
E.g:
input[0] = A1
alphabet = A
number = 1
input[1] = KW
alphabet1 = K
alphabet2 = W
Then add it to a list.
list = ['A1, KW']
I hope you guys know what I mean.

Basic String manipulation.
There are lots of tutorials out there on that, go look them up.
From your question, it looks like you would want to use the isalpha() builtin.
Here's a function that should do the string manipulation like you said.
def pair(user):
user=user.split(" ")
for x in range(len(user)):
print ("\nPair part "+str(x)+":")
for char in user[x]:
if char.isalpha():
print ("Alphabet: "+char)
else:
print ("Number: "+char)
then you can call it with:
print("example pair was 'A1 KW'")
pair("A1 KW")
pair(input("\nEnter your pair: "))
output:
example pair was 'A1 KW'
Pair part 0:
Alphabet: A
Number: 1
Pair part 1:
Alphabet: K
Alphabet: W
Enter your pair: AB 3F
Pair part 0:
Alphabet: A
Alphabet: B
Pair part 1:
Number: 3
Alphabet: F

Related

How to count words that end with a letter? (python)

I am a beginner and this is what I came up with so far. However, it does not output the correct number of words that end with "a" or "b." Any tips on how to correct this code?
names = input("Enter list of names: ")
name = names.split(" ")
num = len(name)
ab = ""
print("Number of words:", num)
for i in range(num):
if name[i] == ' ':
if name[i-1] == a:
ab.append() + " "
elif name[i-1] == b:
ab.append() + " "
a_b = ab.split(' ')
print("Number of words that end with a or b: ",len(a_b))
In Python boolean (True and False) are the same as the integers 1 and 0. This means you can use sum() to count True booleans. str.endswith() returns a boolean. This means you can just do this:
words = ["stab", "drama", "hello", "magma", "test"]
a_b = sum(word.endswith(('a', 'b')) for word in words)
# 3
z_c = sum(word.endswith(('z', 'c')) for word in words)
# 0
Any tips on how to correct this code?
Others have answered alternative, working solutions, but I want to try to point out the specific things wrong in your code snippet and tips to correct.
First here's a copy of your snippet with some simple debugging prints along with their output (running in python 3.10).
names = "Barry Lima Bab"
name = names.split(" ")
print(f"{name=}") # name=['Barry', 'Lima', 'Bab']
num = len(name)
print(f"{num=}") # num=3
ab = ""
print("Number of words:", num)
for i in range(num):
print(name[i]) # Barry -> Lima -> Bab
if name[i] == ' ':
if name[i-1] == a:
ab.append() + " "
elif name[i-1] == b:
ab.append() + " "
print(f"{ab=}") # ab=''
a_b = ab.split(' ')
print(f"{a_b=}") # a_b=['']
Breaking things down step by step like this is a great starting point for better understanding what's going on.
if name[i] == ' ': Notice the value of name[i] so this check never resolves to True meaning the code inside never runs
if the inner code did run, you'd hit a NameError: name 'a' is not defined. Did you mean: 'ab'? because a is undefined. Probably meant 'a' here. same for b
In my example, name[i-1] would be 'Bab' -> 'Barry' -> 'Lima' which is probably not what you're expecting. This is because you're getting the -1th, 0th, 1st items in name. to get the last letter from the name, you want name[i][-1] here
if you then get into either of the furthest inside conditions, you'd encounter AttributeError: 'str' object has no attribute 'append' which happens because append is for list not str. You couldchange ab to be a list to use this in which case you'd want ab.append(name[i]) or you can use string concatenation like ab += " " + name[i] or using str.concat
1 last note of interest, you may have noticed your code as-is really likes to return and say that there's 1 item. This is because the above issues always (if the program doesn't break) leaves ab == '' and ''.split(' ') => [''] and thus len(ab.split(" ")) => 1
1 tip that I think would help in code comprehension is that the name variable here is not a single name string like it implies. It's actually a list[str]. I'd probably denote the variables something more like names_str: str vs names: list[str] or raw_names vs names. Then just use something like for name in names: and not worry about indexes. You can also use name.endswith('a') instead of name[-1] == 'a' for better readability.
Eventually you can combine these into a list comprehension for maximal succinctness -> len([name for name in names if name.endswith('a') or name.endswith('b')]).
words = ["ab", "bab", "pa", "pap"]
result = 0
for word in words:
if word[-1] in "ab":
result += 1
print(result)
As a list comprehension:
words = ["word1a", "word2b", "word3", "word4", "word5a"] # ['word1a', 'word2b', 'word5a']
filtered_words = [word for word in words if word[-1] in "ab"]
filtered_words = [word for word in words if word.endswith(("a", "b"))] # better, if you have multiple endings you want to search for with different lengths
len(filtered_words) # 3
name[i-1] is the previous name in the list, not the last character of the current name in the loop.
There's no need to append the matching names to a string. If you just need the count of matches, increment a counter variable.
You need to put a and b in quotes to make them strings, not variables.
names = input("Enter list of names: ")
name = names.split(" ")
matches = 0
print("Number of words:", len(name))
for cur_name in name:
if cur_name.endswith('a') or cur_name.endswith('b'):
matches += 1
print("Number of words that end with a or b: ", matches)
Use the endswith string method to detect if the last letter is "a" or "b"
names = ["bob","boba","larry","curly","moe"]
count = 0
for name in names:
if name.endswith("a") or name.endswith("b"):
count += 1
print(f"{count=}") # count=2

Finding a word from a text dictionary with given random letters

When a person enters a function (e.g. find_from_dict(letters)), the function searches a word from dictionary.txt that can be made from the letters that the user has inputted—a word that contains the most letters inputted).
For example, letters is input as random typing such as "BAJPPNLE" which will then find "APPLE" from the dictionary since "APPLE" has the most letters from "BAJPPNLE".
def find_from_dict(letters):
n = 0
y = 0
x = 0
dictFile = [line.rstrip('\n') for line in open("dictionary.txt")]
listLetters = list(letters)
final = []
while True:
if n < len(dictFile) and len(list(dictFile[n])) <= len(listLetters) and x < len(list(dictFile[n])) and list(dictFile[n])[x] in listLetters:
x = x + 1
elif n < len(dictFile) and len(list(dictFile[n])) <= len(listLetters) and x < len(list(dictFile[n])) and list(dictFile[n])[x] not in listLetters:
x = 0
n = n + 1
elif n < len(dictFile) and len(list(dictFile[n])) <= len(listLetters) and x == len(list(dictFile[n])):
final.append(dictFile[n])
elif n < len(dictFile) and len(list(dictFile[n])) > len(listLetters):
n = n + 1
else:
print(final)
break
I have this code at the moment, but since my dictionary.txt file is huge and the code is inefficient, it takes forever to go through..
Does anyone have any idea how I could make this code efficient?
You can speed this up by preparing a word index formed of the sorted letters in your word list. Then look for sorted combinations of the letters in that index:
for example:
from collections import defaultdict
from itertools import combinations
with open("/usr/share/dict/words","r") as wordList:
words = defaultdict(list)
for word in wordList.read().upper().split("\n"):
words[tuple(sorted(word))].append(word) # index by sorted letters
def findWords(letters):
for size in range(len(letters),2,-1): # from large to small (minimum 3 letters)
for combo in combinations(sorted(letters),size): # combinations of that size
for word in (w for w in words[combo]): # matching fords from index
yield word # return as you go (iterator)
# If you only want one, change this to: return word
testing:
while True:
letters = input("Enter letters:")
if not letters: break
for word in findWords(letters.upper()):
stop = input(word)
if stop: break
print("")
sample output:
Enter letters:BAJPPNLE
JELAB
BEJAN
LEBAN
NABLE
PEBAN
PEBAN
ALPEN
NEPAL
PANEL
PENAL
PLANE
ALPEN
NEPAL
PANEL
PENAL
PLANE
APPLE
NAPPE.
Enter letters:EPROING
PERIGON
PIGEON
IGNORE
REGION
PROGNE
OPINER.
Enter letters:
if you need a solution without using libraries, you will need to use a recursive approach that does a breadth first traversal of the combination tree:
with open("/usr/share/dict/words","r") as wordList:
words = dict()
for word in wordList.read().upper().split("\n"):
words.setdefault(tuple(sorted(word)),list()).append(word) # index by sorted letters
def findWords(letters,size=None):
if size == None:
letters = sorted(letters)
for size in range(len(letters),2,-1):
for word in findWords(letters,size): yield word
elif len(letters) == size:
for word in words.get(tuple(letters),[]): yield word
elif len(letters)>size:
for i in range(len(letters)):
for word in findWords(letters[:i]+letters[i+1:],size):
yield word
You can kind of "cheat" your way through it by pre-processing the dictionary file.
The idea is: instead of having a list of words, you have a list of groups which is determined by the sorted letters of the words.
For example, something like:
"aeegr": [
"agree",
"eager",
],
"alps": [
"alps",
"laps",
"pals",
]
Then if you wanted to just find the exact match, you could sort the letters from the input and search in the processed file.
But you want the one that matches the most letters, so what you could do is number the letters with prime numbers (I'm only considering lowercase ascii characters), so that a is 2, b is 3, c is 5, d is 7 and so on.
Then, you can get a number by multiplying all the letters, so for example for alps you'd get 2*37*53*67.
In your dictionary file you then have the numbers obtained the same way for each word.
Like:
262774: [
"alps",
"laps",
"pals",
]
You then go through your dictionary and if the initial number divided by the dictionary number has a remainder of 0, that's a possible match.
The maximum number with a remainder of 0 is the one that you want, because that's the one with the most letters present.
Keep in mind that the numbers might get very big very quickly, depending on how many letters you use.

How to check if a character is in an 2d array and then print the corresponding values

I want to create a program that asks the user for a word. Gives each character in the alphabet a number and then prints out the number for each character in the word they have guessed.
I have seemed to confuse myself with the code I have created. Any advice?
T2 = [["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
["_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_",]]
for i in range(0,26,1):
T2[1][i] = list2[i]
list2 = []
for i in range(100):
r = random.randint(0,26)
if r not in list2: list2.append(r)
list3 = []
for i in range(26):
r = random.randint(0,5)
if r not in list3: list3.append(r)
for i in range(0,26,1):
T2[1][i] = list2[i]
for r in T2:
for c in r:
print(c,end = " ")
print()
guesses = ''
wordtoprint=""
word = input("What is the secret word? ").lower().strip()
for char in word:
if char in T2[0]:
char = T2[][i]
wordtoprint=wordtoprint+char+" "
print(wordtoprint)
i would like to see an output of
if the user inputted the word hello
output the output would be the numbers those letters correspond with.
ie 23 4 8 8 13
I think that a dictionary will help you a lot. Instead of...
T2 = [["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
["_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_","_",]]
for i in range(0,26,1):
T2[1][i] = list2[i]
Use something like that...
import string
all_letters = enumerate(string.ascii_uppercase, 1)
pairs = []
for pair in all_letters:
pairs.append( pair[::-1] )
T2 = dict(pairs)
Now you can map each letter to a number easily.

multiplying letter of string by digits of number

I want to multiply letter of string by digits of number. For example for a word "number" and number "123"
output would be "nuummmbeerrr". How do I create a function that does this? My code is not usefull, because it doesn't work.
I have only this
def new_word(s):
b=""
for i in range(len(s)):
if i % 2 == 0:
b = b + s[i] * int(s[i+1])
return b
for new_word('a3n5z1') output is aaannnnnz .
Using list comprehension and without itertools:
number = 123
word = "number"
new_word = "".join([character*n for (n, character) in zip(([int(c) for c in str(number)]*len(str(number)))[0:len(word)], word)])
print(new_word)
# > 'nuummmbeerrr'
What it does (with more details) is the following:
number = 123
word = "number"
# the first trick is to link each character in the word to the number that we want
# for this, we multiply the number as a string and split it so that we get a list...
# ... with length equal to the length of the word
numbers_to_characters = ([int(c) for c in str(number)]*len(str(number)))[0:len(word)]
print(numbers_to_characters)
# > [1, 2, 3, 1, 2, 3]
# then, we initialize an empty list to contain the repeated characters of the new word
repeated_characters_as_list = []
# we loop over each number in numbers_to_letters and each character in the word
for (n, character) in zip(numbers_to_characters, word):
repeated_characters_as_list.append(character*n)
print(repeated_characters_as_list)
# > ['n', 'uu', 'mmm', 'b', 'ee', 'rrr']
new_word = "".join(repeated_characters_as_list)
print(new_word)
# > 'nuummmbeerrr'
This will solve your issue, feel free to modify it to fit your needs.
from itertools import cycle
numbers = cycle("123")
word = "number"
output = []
for letter in word:
output += [letter for _ in range(int(next(numbers)))]
string_output = ''.join(output)
EDIT:
Since you're a beginner This will be easier to understand for you, even though I suggest reading up on the itertools module since its the right tool for this kind of stuff.
number = "123"
word = "number"
output = []
i = 0
for letter in word:
if(i == len(number)):
i = 0
output += [letter for _ in range(int(number[i]))]
i += 1
string_output = ''.join(output)
print(string_output)
you can use zip to match each digit to its respective char in the word (using itertools.cycle for the case the word is longer), then just multiply the char by that digit, and finally join to a single string.
try this:
from itertools import cycle
word = "number"
number = 123
number_digits = [int(d) for d in str(number)]
result = "".join(letter*num for letter,num in zip(word,cycle(number_digits)))
print(result)
Output:
nuummmbeerrr

Replace an item in a list based on user input

I'm a noob so please excuse me.
There are three lists
A list of letters L = ['A','B','C','D','E']
A list of numbers N = ['1','2','3','4','5']
A list of number strings List = ['124','351']
These are the steps I wish to achieve
Request a letter from the user e.g. A
Find the letter in the letter list L and record its numerical position e.g. [0]
Use the same numeric position in the list of numbers N and record the
number that's there e.g. 1
Replace the instances of the number found in the non-letter strings List e.g. ['124','351'] becomes ['A24','35A']
Ask the user for the next letter until all the number strings become letters.
What I have achieved so far is the first 4 steps. After step 4 I thought to check if the number strings still contained numbers and if so go to step 5. I can't seem to work out how to get the code to check if the number strings contain any more number. NOTE: The number list is not limited to numbers. It could contain math symbols e.g. + or -
L = ['A','B','C','D','E']
N = ['1','2','3','4','5']
list = ['124','351']
print ("Enter a letter")
# Is there a number in List
# If yes then do the following else print List
# Ask for a letter from the user
letter = input ("Enter letter: ")
# Confirm whether the letter is correct or not
if letter in L:
# Find the position of the letter in the list
position = (L.index(letter));
# Make a variable called number with value at the same position in the N list
number = N[position];
# Replace the numbers in the List with the letter entered
list = [item.replace(number, letter) for item in list];
# Print the list with the numbers replaced
print (list, "\n");
print ("Please guess again. \n");
letter = input ("Enter a letter now: ")
# repeat until the List only contains letters
else:
print ("That is not correct");
print ("Please guess again. \n");
letter = input ("Enter a letter now: ")
I hope that is OK. If you need anything further please let me know
L = ['A','B','C','D','E']
N = ['1','2','3','4','5']
n_strings = ['124','351'] # Don't use list as a variable name
while not all( x.isalpha() for x in n_strings): # keep going until all are alpha chars
print ("Enter a letter")
# Is there a number in List
# If yes then do the following else print List
# Ask for a letter from the user
letter = input("Enter letter: ")
# Confirm whether the letter is correct or not
if letter in L:
# Find the position of the letter in the list
position = (L.index(letter));
# Make a variable called number with value at the same position in the N list
number = N[position];
# Replace the numbers in the List with the letter entered
n_strings = [item.replace(number, letter) for item in n_strings];
# Print the list with the numbers replaced
print (n_strings, "\n");
print ("Please guess again. \n");
letter = input("Enter a letter now: ")
# repeat until the List only contains letters
else:
print ("That is not correct");
print ("Please guess again. \n");
letter = input("Enter a letter now: ")
You could change the logic and shorten the code.
while True:
if all(x.isalpha() for x in n_strings ):
print("All guessed correct {}".format(n_strings)) # if all are alpha print final n_string and break out of loop
break
print n_strings
letter = input("Please enter a letter: ")
if letter in L:
# Find the position of the letter in the list
position = (L.index(letter));
number = N[position];
n_strings = [item.replace(number, letter) for item in n_strings];
print (n_strings, "\n");
# repeat until the List only contains letters
else:
print ("That is not correct");
print ("Please guess again. \n");
I can't seem to work out how to get the code to check if the number
strings contain any more number
You could define a function that loops over the list to see if any of the entries have digits using using isdigit() like so
def has_number(lst):
for s in lst:
if any(x.isdigit() for x in s):
return True
return False
This will return True if any of the entries in your number string list contains a number
Saw your edit
My goal is for it to contain letters only
To do that you could just check like this
if all(x.isalpha() for x in lst):
# lst contains only entries that consists of letters
This uses isalpha()
str.isalpha()
Return true if all characters in the string are
alphabetic and there is at least one character, false otherwise.
Demonstration:
>>> all(x.isalpha() for x in ['abc', 'def'])
True
>>> all(x.isalpha() for x in ['ab1', 'def'])
False

Categories

Resources