It's in the indents (I think) Python - python

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()

Related

Python: How to replace string elements using an array of tuples?

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?"

How to print a list from user input sentence?

So I am supposed to make a script that asks user to make a sentence then discard all characters but lower case and print the lower case letters like this ['m', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'].
My script:
#!/usr/bin/python3
sentence = input("Enter a sentence: ")
for letter in sentence:
if letter.islower():
print(letter)
and this is the output:
o
e
s
h
i
s
w
r
k
Seems like you want to produce a list, you have list comprehensions to make life easy:
l = ['P', 'm', 'y', 'H', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']
out = [i for i in l if i.islower()]
print(out)
# ['m', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']
Which is equivalent to:
out = []
for i in l:
if i.islower():
out.append(i)
print(out)
# ['m', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']
You might be looking for end = ",":
sentence = input("Enter a sentence: ")
for letter in sentence:
if letter.islower():
print(letter, end=",")
# ^^^
Your program is almost OK, only instead of printing every lowercase character, append it to a list, and finally print only that list:
sentence = input("Enter a sentence: ")
lowercases = [] # prepare an empty list
for letter in sentence:
if letter.islower():
lowercases.append(letter)
print(lowercases) # print the filled list
Test:
Enter a sentence: The End of Universe.
['h', 'e', 'n', 'd', 'o', 'f', 'n', 'i', 'v', 'e', 'r', 's', 'e']

Why is this only printing one letter every time I try?

from random import choice
print ("Enigma")
list = ['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']
range (0,25)
cha2 = choice(list)
complete = choice(list)
for x in range (0, 90000):
("Type alphabet")
cha1=input()
print (complete)
When I run it and input an alphabet the same alphabet outputs as the first time. However I want it to output a different random alphabet each time I enter an alphabet. Thanks
Chris_Rands has it right in the comments...
complete = choice(list) is the line that choose a letter to return, and you are only running it one time. If you wanted it to run every time, you need to put it inside your while loop:
from random import choice
print ("Enigma")
list = ['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 x in range (0, 90000):
("Type alphabet")
cha1=input()
complete = choice(list) # This is the key change here
print (complete)
To answer: "I want it to output a different random alphabet each time I enter an alphabet"
From the above, you will check cha1 against the complete, and while they are the same, keep calling choice to update
cha1=input()
complete = choice(list)
while cha1 == complete:
complete = choice(list)

How to check if one string's characters exist and are in the same position as those in another string?

I have a list containing the characters of this string:
wordtoguess = ['T', 'R', 'A', 'N', 'S', 'M', 'I', 'S', 'S', 'I', 'O', 'N']
And I have the user guess a word and store it in the variable 'guessed'. I also have a variable called 'correct_chars' which is equal to 0.
guessed = input()
correct_chars = 0
When the user guesses a word I want Python to iterate through each character of the word and if it exists and is in the same place as the corresponding character in wordtoguess, to add 1 to correct_chars. For example if the user inputted the string 'translations', then correct_chars would be equal to 5. I have been unable to figure out how to do this so far.
Here's a potential implementation:
>>> wordtoguess = "TRANSMISSION"
>>> guessed = "TRANSLATIONS"
>>> correct_chars = sum(1 for (x, y) in zip(wordtoguess, guessed) if x.lower() == y.lower())
>>> correct_chars
5
guessed = input()
correct_chars = 0
wordtoguess = ['T', 'R', 'A', 'N', 'S', 'M', 'I', 'S', 'S', 'I', 'O', 'N']
for i, c in enumerate(guessed):
try:
if c.upper() == wordtoguess[i]:
correct_chars += 1
except IndexError:
pass
print(correct_chars)
Here's a possible solution
guessed = input()
correct_chars = 0
wordtoguess = ['T', 'R', 'A', 'N', 'S', 'M', 'I', 'S', 'S', 'I', 'O', 'N']
for i in range( len(wordtoguess) ):
if i >= len(guessed):
break
if wordtoguess[i] == guessed[i]:
correct_chars = 0

Getting wrong output when working with tuple and list in Python

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 '!'

Categories