Related
I'm trying to replace the characters of the reversed alphabet with those of the alphabet. This is what I've got:
alphabet = ['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']
rev_alphabet = alphabet[::-1]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
def f(alph, rev_alph):
return (alph, rev_alph)
char_list_of_tups = list(map(f, alphabet, rev_alphabet))
for alph, rev_alph in char_list_of_tups:
sample = sample.replace(rev_alph, alph)
print(sample)
expected output: did you see last night's episode?
actual output: wrw you svv ozst nrtst's vprsowv?
I understand that I'm printing the last "replacement" of the whole iteration. How can I avoid this without appending it to a list and then running into problems with the spacing of the words?
Your problem here is that you lose data as you perform each replacement; for a simple example, consider an input of "az". On the first replacement pass, you replace 'z' with 'a', and now have "aa". When you get to replacing 'a' with 'z', it becomes "zz", because you can't tell the difference between an already replaced character and one that's still unchanged.
For single character replacements, you want to use the str.translate method (and the not strictly required, but useful helper function, str.maketrans), to do character by character transliteration across the string in a single pass.
from string import ascii_lowercase # No need to define the alphabet; Python provides it
# You can use the original str form, no list needed
# Do this once up front, and reuse it for as many translate calls as you like
trans_map = str.maketrans(ascii_lowercase[::-1], ascii_lowercase)
sample = sample.translate(trans_map)
alphabet = ['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']
# or
alphabet = [chr(97 + i) for i in range(0,26)]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
res = []
for ch in sample:
if ch in alphabet:
res.append(alphabet[-1 - alphabet.index(ch)])
else:
res.append(ch)
print("".join(res))
Another Way if you are ok with creating a new string instead.
alphabet = ['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']
dictRev = dict(zip(alphabet, alphabet[::-1]))
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
s1="".join([dictRev.get(char, char) for char in sample])
print(s1)
"did you see last night's episode?"
I have a list of symbols:
symbols_list = ['*','†','‡','§','¶','#']
and a longer list of elements as:
note_list = ['a','b','c','d'.....'z']
I want to join them in a dictionary to look like this:
{'*':'a','†':'b','‡':'c','§':'d','¶':'e','#':'f','**':'g','††':'h'...'***':'m'...etc. }
so basically the symbols_list values would repeat as *, **, ***, **** etc.
I tried to just get the symbols_list to be the same length at first using:
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a])
but it ended up doubling the elements each iteration instead of just adding one character each time
['*',
'†',
'‡',
'§',
'¶',
'#',
'**',
'††',
'‡‡',
'§§',
'¶¶',
'##',
'****',
'††††',
'‡‡‡‡',
'§§§§',
'¶¶¶¶',
'####',
'********',
'††††††††',
'‡‡‡‡‡‡‡‡',
'§§§§§§§§',
'¶¶¶¶¶¶¶¶',
'########',
'****************']
I thought it would be easier to make the symbols_list the same size first, and then combine them into a dictionary.
I couldn't resist trying to do it with itertools.
from itertools import chain, count
# yields *, †, ... **, ††, ... infinitely
symbol_generator = chain.from_iterable(((i*x for x in symbols_list) for i in count(1)))
{s:c for s,c in zip(symbol_generator, abc)}
{'*': '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'}
Maybe do it like this:
new_symbols_list = []
for i in range(len(note_list)//len(symbols_list)+1):
new_symbols_list += [k*(i+1) for k in symbols_list]
output = {s: l for s, l in zip(new_symbols_list[:len(note_list)], note_list)}
>>> output
{'*': '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 a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a])
You append symbols_list[a]+symbols_list[a], which essentially doubles symbols_list[a]. You just want to add the first character of symbols_list[a] to itself, so do
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a][0])
Here is a oneliner:
{ (int(i/len(symbols_list))+1)*symbols_list[i%len(symbols_list)] : e for i, e in enumerate(note_list) }
I have a long list of words that I'm trying to go through and if the word contains a specific character remove it. However, the solution I thought would work doesn't and doesn't remove any words
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
validwords = []
for i in l3:
for x in firstchect:
if i not in x:
validwords.append(x)
continue
else:
break
If a word from firstcheck has a character from l3 I want it removed or not added to this other list. I tried it both ways. Can anyone offer insight on what could be going wrong? I'm pretty sure I could use some list comprehension but I'm not very good at that.
The accepted answer makes use of np.sum which means importing a huge numerical library to perform a simple task that the Python kernel can easily do by itself:
validwords = [w for w in firstcheck if all(c not in w for c in l3)]
you can use a list comprehension:
import numpy as np
[w for w in firstcheck if np.sum([c in w for c in l3])==0]
It seems all the words contain at least 1 char from l3 and the output of above is an empty list.
If firstcheck is defined as below:
firstcheck = ['a', 'z', 'poach', 'omnificent']
The code should output:
['a', 'z']
If you want to avoid all loops etc, you can use re directly.
import re
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['azz', 'poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
# Create a regex string to remove.
strings_to_remove = "[{}]".format("".join(l3))
validwords = [x for x in firstcheck if re.sub(strings_to_remove, '', x) == x]
print(validwords)
Output:
['azz']
Ah, there was some mistake in code, rest was fine:
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['aza', 'ca', 'poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
validwords = []
flag=1
for x in firstcheck:
for i in l3:
if i not in x:
flag=1
else:
flag=0
break
if(flag==1):
validwords.append(x)
print(validwords)
So, here the first mistake was, the for loops, we need to iterate through words first then, through l3, to avoid the readdition of elements.
Next, firstcheck spelling was wrong in 'for x in firstcheck` due to which error was there.
Also, I added a flag, such that if flag value is 1 it will add the element in validwords.
To, check I added new elements as 'aza' and 'ca', due to which, now it shows correct o/p as 'aza' and 'ca'.
Hope this helps you.
This is a program that works kinda like a Boggle game. It rolls 16 dice and then you have to pick words out of the rolled letters. Not fancy enough to do the connected dice, just any words longer than 3 from the given letters. It checks the words against a word list and to make sure you don't repeat
This is still basic in scope and very I'm still new to Python 3.3.4.
I think the error is in the indention of the loops in get_guesses(). I have tried moving loops around different loops work at different times.
import random
global roll
global rolled
global guesses
global word_list
global start
roll = []
rolled = []
word_list = []
guesses = []
# Setting the dice
die0 = ['r', 'i', 'f', 'o', 'b', 'x']
die1 = ['i', 'f', 'e', 'h', 'e', 'y']
die2 = ['d', 'e', 'n', 'o', 'w', 's']
die3 = ['u', 't', 'o', 'k', 'n', 'd']
die4 = ['h', 'm', 's', 'r', 'a', 'o']
die5 = ['l', 'u', 'p', 'e', 't', 's']
die6 = ['a', 'c', 'i', 't', 'o', 'a']
die7 = ['y', 'l', 'g', 'k', 'u', 'e']
die8 = ['qu', 'b', 'm', 'j', 'o', 'a']
die9 = ['e', 'h', 'i', 's', 'p', 'n']
die10 = ['v', 'e', 't', 'i', 'g', 'n']
die11 = ['b', 'a', 'l', 'i', 'y', 't']
die12 = ['e', 'z', 'a', 'v', 'n', 'd']
die13 = ['r', 'a', 'l', 'e', 's', 'c']
die14 = ['u', 'w', 'i', 'l', 'r', 'g']
die15 = ['p', 'a', 'c', 'e', 'm', 'd']
dice = [die0, die1, die2, die3, die4, die5, die6, die7, die8, die9, die10, die11, die12, die13, die14, die15]
# Importing word list and file handling
def dict():
game_list = open('TWL06.txt')
for line in game_list:
line=line.strip()
word_list.append(line)
game_list.close()
# Randomly gets a roll from the dice
def dice_roll():
global roll
global rolled
for die in dice:
roll.append(random.choice(die))
rolled = ' '.join(roll)
# breaks the rolled dice into 4 groups of 4
def game_grid():
print (rolled[0:8])
print (rolled[8:16])
print (rolled[16:24])
print (rolled[24:32])
get_guesses()
# Get player input for guessed words
def get_guesses():
global word_list
global rolled
guess = input("Enter a word you found.").upper()
guess_list = list(guesses)
if (len(guess)) <= 3:
print("That word is to short.")
get_guesses()
else:
if guess in word_list:
for i in guess_list:
if i not in rolled:
print("That word is not in the dice.")
get_guesses()
if guess not in guesses:
print("That is a good word.")
guesses.append(guess)
get_guesses()
else:
print("You already guessed that one.")
get_guesses()
else:
print("That is not one of the ", len(word_list), "words I know.")
get_guesses()
# Main menu
def main():
print("This game is similar to Boggle")
print("Your goal is to guess as many words from the rolled dice as you can.")
print("You can use any letters in the grid to play.")
print("Your words must be 3 letters or longer.")
play_quit = input("Press 'p' to play or any other key to quit.").lower()
if play_quit == "p":
dict()
dice_roll()
game_grid()
else:
print("Thanks for playing.")
main()
Presumably you intend guess_list to be a list of the characters in the user's guest, but in fact you are setting it to a copy of guesses, the list of the user's prior words.
Also, you are converting the user's input to upper case, but your randomly-chosen letters are lower case, so you would never find the characters of the user's input in rolled anyway. I don't know what case is used by the contents of TWL06.txt.
Many of the names in this program can be improved.
You have a function named dict, which is a bad idea because dict is a built-in function that creates dictionaries.
You have a variable named game_list which is a file, not a list.
You have a variable named word_list, which is a list, but words would be more concise and just as useful.
You have variables named die0, die1, die2, etc., which are not necessary. You can just create dice using nested list literals.
An iteration variable named i implies an integer, but you intend it to be a character.
Also, you use global in a lot of places that you don't need it. You only need it when you're going to assign to a global variable and your assignment statement is in a function. When you call append on a global variable, that doesn't assign to the variable.
import random
acceptable_words = []
acceptable_letters = []
user_words = []
dice = [
['r', 'i', 'f', 'o', 'b', 'x'],
['i', 'f', 'e', 'h', 'e', 'y'],
['d', 'e', 'n', 'o', 'w', 's'],
['u', 't', 'o', 'k', 'n', 'd'],
['h', 'm', 's', 'r', 'a', 'o'],
['l', 'u', 'p', 'e', 't', 's'],
['a', 'c', 'i', 't', 'o', 'a'],
['y', 'l', 'g', 'k', 'u', 'e'],
['qu', 'b', 'm', 'j', 'o', 'a'],
['e', 'h', 'i', 's', 'p', 'n'],
['v', 'e', 't', 'i', 'g', 'n'],
['b', 'a', 'l', 'i', 'y', 't'],
['e', 'z', 'a', 'v', 'n', 'd'],
['r', 'a', 'l', 'e', 's', 'c'],
['u', 'w', 'i', 'l', 'r', 'g'],
['p', 'a', 'c', 'e', 'm', 'd']]
def load_acceptable_words():
with open('TWL06.txt') as word_file:
for line in word_file:
acceptable_words.append(line.strip().lower())
def roll_dice():
for die in dice:
acceptable_letters.append(random.choice(die))
def print_game_grid():
for i in range(4):
print_game_row(i)
def print_game_row(i):
print (' '.join(acceptable_letters[i:i+4]))
def run_game_loop():
while True:
run_one_turn()
def run_one_turn():
candidate = input("Enter a word you found.").strip().lower()
if (check_is_long_enough(candidate)
and check_can_be_spelled(candidate)
and check_is_acceptable_word(candidate)):
accept_user_word(candidate)
def check_is_long_enough(candidate):
if len(candidate) >= 3:
return True
else:
print("That word is to short.")
return False
def check_can_be_spelled(candidate):
if all(letter in acceptable_letters for letter in candidate):
return True
else:
print("That word is not in the dice.")
return False
def check_is_acceptable_word(candidate):
if candidate in acceptable_words:
return True
else:
print("That is not one of the ", len(acceptable_words), "words I know.")
return False
def accept_user_word(word):
user_words.append(word)
def main():
print("This game is similar to Boggle.")
print("Your goal is to guess as many words from the rolled dice as you can.")
print("You can use any letters in the grid to play.")
print("Your words must be 3 letters or longer.")
play_quit = input("Press 'p' to play or any other key to quit.").strip().lower()
if play_quit == "p":
load_acceptable_words()
roll_dice()
print_game_grid()
run_game_loop()
else:
print("Thanks for not playing.")
main()
Trying to learn some python and I have the following task:
Get a phrase from the user as an input.
Check if the input contains a consonant from a consonants tuple\list that I declare in the code.
For every consonant in the user input, print the consonant followed by the letter 'o' and the consonant itself.
For example:
User types the word 'something' as an input
Output should be: 'sosomometothohinongog' (vowels do not exist in the
consonant tuple and hence are not being appended).
This is my code:
#!/usr/bin/python
consonant = ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z')
def isConsonant(user):
for consonant in user:
print consonant + "o" + consonant
var = raw_input("type smth: ")
isConsonant(var)
Here is what I get:
root#kali:~/py_chal# ./5.py
type smth: test
tot
eoe
sos
tot
I have trouble with:
The code treats vowels as consonants even though they are not in the
list (notice the 'e').
the 'print' method adds a new line - This was solved by importing the
sys module and using 'write'.
Any tips are greatly appreciated.
consonant = ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z')
def isConsonant(user):
for letter in user:
if letter in consonant:
print letter + "o" + letter
var = raw_input("type smth: ")
isConsonant(var)
OR
consonant = ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z')
print "\n".join(["%so%s" % ( letter, letter) for letter in raw_input("type smth: ") if letter in consonant])
OR maybe
print "\n".join(["%so%s" % (l,l) for l in set(raw_input("type smth: ")).difference('aeiou')])
You can easily print without adding a new line at the end without importing anything by adding a , at the end of print like this:
print 'hello ',
print 'world',
print '!'