Python code works in 2.7 but not in 3.5 - python

My coursework is to create Tic Tac Toe in Python, my tutor helped me get it working in 2.7 however It needs to be in 3.5.
Firstly in 2.7 the code below prints a 3x3 list, however in 3.5 it just prints the list downwards not 3x3. my tutor said maybe put end = ' ' at the end but that also doesn't work.
def printBoard( board ):
counter = 0
for y in range(3):
for x in range(3):
print (board[counter]),
counter += 1
print
print
second problem is on 2.7 it allows me to continue to input numbers till the board is filled with X or O, on 3.5 it only allows to input once and then the program ends?
value = input("input number between 1 and 9")
value = int(value)
if value == 1:
alist[0] = player1
printBoard( alist )
value = input("input number between 1 and 9")
if value == 2:
alist[1] = player1
printBoard( alist )
value = input("input number between 1 and 9")
etc.

print changed from statement to a function in Python 3.x. To print a statement without newline, you need to pass end=' ' parameter (You can use the print as a function in Python 2.7 if you put from __future__ import print_function at the beginning of the code):
print(board[counter], end=' ')
input returns a string in Python 3.x. (does not evaluate the input string). You need to convert the value into int every where you used input:
value = input("input number between 1 and 9")
value = int(value)
Alternatively, instead of comparing the input with integer literal 1 or 2, compare the input string with strings: '1', '2' without converting the string into integer. (But this requires you to use raw_input in Python 2.7 instead of input)
print should be called: print(). Otherwise, nothing is printed.

I assume board is something like [['*', '*', '*'], ['*', '*', '*'], ['*', '*', '*']]. That means you have an easy way of printing this with a single print() call.
print(*(''.join(row) for row in board), sep='\n')
This joins each row into a new string, producing each row as part of a generator. This generator is unpacked with * and sent to print(), where each row is separated by a newline.
For your second issue, the problem is simple: you cast int() for the first value, but not for the subsequent ones. However, this is the sort of thing you should be doing with a loop. It'll prevent exactly this kind of bug. If you find yourself writing lots of code with Ctrl+V, you're doing something wrong. If each block is slightly different, with an incremented number, you would do that with something like for i in range(n):, which allows you to execute the same code with an incremented number on each iteration.
However, I'd recommend a simple while loop that checks if the game is complete:
while True:
move = request_move()
do_move('X', move)
if game_complete():
break
request_move()
do_move('O', move)
if game_complete():
break
You would then write appropriate functions to request move coordinates, input moves into the board, and check if the game is complete yet.

Related

inputted list keeps being interpreted as string

So I made this little code at school, and i know that input() can understand lists as is. I tried it again at home but it doesnt work. My school computer has python 2. something while my laptop has 3.4.
The code looks like this
a = input()
list = []
count = 0
for y in range(1, len(a)):
min = a[count]
for x in range(count +1, len(a)):
if min > a[x]:
min = a[x]
print(min)
a[count] = min #str object does not support item assignment
count=count+1
print (a)
I want to input a list such as [1,2,3,4,5] but what happens is, it reads the whole thing as a string, along with the commas, when i want to see it as a list of integers.
Python 3's input returns a string (same as Python 2's raw_input), whilst Python 2's input evaluates the text. To get similar behaviour, if you've got a valid Python list that can be evaluated, then you can use ast.literal_eval, eg:
import ast
a = ast.literal_eval(input())
# do other stuff with `a` here...
So you'd enter something like [1, 2, 3, 4, 5] as your input, and you'll end up with a being a Python list.
I assume your input would be something like: "1 2 3 4 5" -- judging by the code which comes later. This oufcourse is a string. If you want to work with the numbrs in the string as integers you need to:
a = input()
a = map(int, a.split())

Why is this while statement looping infinitely?

I am using Python 2.7 in Windows PowerShell.
def loop(loop):
i = 0
numbers = []
while i < loop:
print "At the top i is %d" % i
numbers.append(i)
i += 1
print "Numbers now: ", numbers
print "At the bottom i is %d" % i
value = raw_input("Choose the loop value:\n>")
print value
loop(value)
When I enter 6 as the input for value, loop() turns into an infinite loop.
Any idea what is going wrong?
The result of your raw_input, the variable value (passed to loop in your function) is a string. You are comparing this to i, an integer. In Python 2.x, all integers are less than all strings, so i < loop is always true no matter how big i gets.
Convert your input to an integer to make the comparison work:
value = int(raw_input("Choose the loop value:\n>"))
(And I'd also suggest not naming your function's argument the same as the function itself; it's just confusing.)
You have to put your raw_input in int().
replace:
value = raw_input("Choose the loop value:\n>")
on:
value = int(raw_input("Choose the loop value:\n>"))
OR you can just change:
while i < loop:
to
while i < int(loop):
I am sure you are actually running loop('6') rather than loop(6).
because value is a string
you should call your function like this
loop(int(value))

Text Based RPG Functioning Error?

So, I'm hard at work on a text-based RPG game on Python 2.7, but I came across a problem in the character menu. Here's what it looks like:
def raceselect(n):
if n==0:
print "(name) the Human."
if n==1:
print "(name) the Dwarf."
if n==2:
print "(name) the Elf."
if n==3:
print "(name) the Halfling."
n = raw_input
raceselect(n)
0, 1, 2, and 3 are all used as raw_input answers on the previous screen when prompted with the options. However, when the script is run, the options are shown, and the input box shows, however when a number is answered the script simply ends. I can't for the life of me figure out what is causing this, unless it's the fact that I used (name) and raw_input earlier in the script, which I doubt. Please help!
--Crux_Haloine
You need to turn the raw input into a int:
n = int(raw_input())
Also, you need to call the function, so use raw_input() rather than just raw_input
n = raw_input here will bring nothing to you. You should use n = int(raw_input()) according to your need. And I think it is better for you to use a dict or list rather than several if:
def raceselect(n):
races = {0: 'Human', 1: 'Dwarf', 2: 'Elf', 3: 'Halfing'}
if n in races:
print '(name) the %s' % races[n]
else:
print 'wrong input'
First issue is this:
n = raw_input
You never actually call the function. Instead, your are assigning a reference of raw_input to n (as in, n is now the function, not the result of the function).
Also, once you call the function, you have to cast it into an integer, because raw_input returns a string.
Thus, you want:
n = int(raw_input()).

GoTo(basic) program

I'm doing some tutorials online, and I'm stuck with an exercise :Write a function getBASIC() which takes no arguments, and does the following: it should keep reading lines from input using a while loop; when it reaches the end it should return the whole program in the form of a list of strings. Example of list of strings:
5 GOTO 30
10 GOTO 20
20 GOTO 10
30 GOTO 40
40 END
I wrote a program, but it doesn't work, however I will post it too:
def getBASIC():
L=[]
while "END" not in L:
L.append(str(input()))
if str(input()).endswith("END"):
break
return L
Also I notice you that I'm not allowed to use IS or RECURSION .
There are several errors:
you call input() twice without appending it to the list the second time
'END' in L determines whether there is 'END' (whole) line in the list L (there isn't)
Note: input()already returns a str object; you don't need to call str() on its returned value.
To read input until you've got empty line you could:
def getBASIC():
return list(iter(input, ''))
Or to read until END is encountered at the end of line:
def getBASIC():
L = []
while True:
line = input()
L.append(line)
if line.endswith("END"):
break #NOTE: it doesn't break even if `line` is empty
return L
Back when I was learning Pascal, we used a priming read for loops that needed at least one iteration. This still works well in Python (I prefer it to a while True / break loop).
By simply testing the last line in the list (rather than the last line read) we eliminate the need for a variable to store the input and can combine the reading and appending operations.
def getBASIC():
lines = [input("]")] # use Applesoft BASIC prompt :-)
while not lines[-1].upper().rstrip().endswith("END"):
lines.append(input("]"))
return lines
try this one:
def get_basic():
L = []
while True:
line = str( input() )
L.append( line )
if "END" in line:
break
return L
Use raw_input() instead of input(). input() function takes string from standard input and tries to execute it as a python source coode. raw_input() will return a string as expected.
You use input() 2 time inside a loop. That means you await two string to be input inside one cycle iteration. You don't need last condition (if statement) inside your while loop. It'll end up when "END" is encountered in L.
The next code should do the job:
def getBASIC():
L=[]
while True:
inp = raw_input()
L.append(inp)
if inp.endswith('END'):
break
return L
Your code has the following problems.
"while "END" not in L" will not work if your input is "40 END"
In Python 2.7, "input()" is equivalent to "eval(raw_input()))". So, Python is trying to evaluate the "GOTO" statements.
"if str(input()).endswith("END"):" does not append input to L
So, here is an updated version of your function:
def getBASIC():
L = []
while True:
# Grab input
L.append(str(raw_input()))
# Check if last input ends with "END"
if L[-1].endswith("END"):
break
return L

Python truncating numbers in integer array

I am teaching myself Python and am running into a strange problem. What I am trying to do is pass a list to a function, and have the function return a list where elements are the sum of the numbers around it, but what I thought would work produced some strange results, so I made a debug version of the code that still exhibts the behavior, which is as follows:
When I make an integer array, and pass it to an function which then uses a for loop print the individual values of the list, the numbers following the first one in each int are truncated.
For example, the following input and output:
Please enter a number: 101
Please enter a number: 202
Please enter a number: 303
Please enter a number: .
1
2
3
This happens no matter the input, if its 10, 101, or 13453 - the same behavior happens.
I know I am probably missing something simple, but for the sake of me, no amount of googling yields me a solution to this issue. Attached below is the code I am using to execute this. It is interesting to note: when printing the entire list outside of the for loop at any point, it returns the full and proper list (ie ['101', '202', '303'])
Thanks!
temp = list()
def sum(list):
print list
for i in range(1, len(list)+1):
print i
return temp
L = list()
while True:
input = raw_input("Please enter a number: ");
if input.strip() == ".":
break
L.append(input);
print L
L2 = sum(L)
print L2
The loop
for i in range(1, len(my_list)+1):
print i
iterates over the numbers from 1 to len(my_list), not over the items of the list. To do the latter, use
for x in my_list:
print x
(I've renamed list to my_list to save you another headache.)
You are printing the counter, not the list item. This is what you want:
for i in list:
print i
list is itself iterable and you don't need a counter to loop it.

Categories

Resources