How to print the reverse but as a string - python

I'm working on this question...and have encountered 2 problems that I am not smart enough to solve. Will you help?
Write a program that reads a list of integers, one per line, until an * is read, then outputs those integers in reverse. For simplicity in coding output, follow each integer, including the last one, by a comma.
Note: Use a while loop to output the integers. DO NOT use reverse() or reversed().
my code
user_input = int(input())
my_list = []
while True:
if user_input >= 0:
my_list.append(user_input)
user_input = int(input())
elif user_input <= 0:
print(my_list[::-1])
break
I need to stop when it hits the * but I don't know how to identify that in the code so for testing I set it to print when a negative number is entered.
I need to print the result in reverse without using reverse() but it has to be printed as a string and not a list. Can't figure out how to do that.

Check whether the input is * before converting it to an integer.
my_list = []
while True:
user_input = input('Enter a number, or * to stop')
if user_input = '*':
break
my_list.append(int(user_input))
while len(my_list) > 0:
print(my_list.pop(), end=",") # remove the last element and print it
print()

So, let's break down the the assignment:
Write a program that reads a list of integers, one per line
This means that you should have a loop that reads in values, converts them into an integer and adds them to a list.
But:
until an * is read
This means that you first have to check that the user's input was equal to "*". But, you'll have to be careful to not try to convert the user's input into an integer before you check if it's an asterisk, otherwise an error will be thrown. So, your loop would look like the following:
Get the user's input
Check if it's an asterisk. If so, break the loop.
If the user's input is not an asterisk, convert it to an int, and then add it to your list of inputted integers.
That's all you need for your first loop.
For the second loop, let's refer to the assignment:
then outputs those integers in reverse
This means that you will need a second loop; a for loop would work - you can have the loop go over a range(), except counting backwards. Here is a post about this exact thing.
Your range would start at the length of your list, minus one, because the last index of the list is one less than the number of items, since list indices start at zero.
Then, you end the range at -1, meaning the range will go down to zero, and stop, because it stops before it gets to the specified end.
Your range will count down by -1, instead of the implicit +1 by default. Refer to that post I linked if you're not sure how to do this.
Lastly, we need to actually print the items at those indices.
follow each integer, including the last one, by a comma.
To me this means that either we could output one integer per line, with a comma at the end of each line, or we could print them all in one line, separated by commas.
If you want everything to print on one line, you can just do a regular print() of the item at the current index, followed by a comma, like print(my_list[a] + ',').
But, if you want to output them on separate lines, you can set the end argument of print() to be a comma. This post explains this.
And that's it!
There are other ways to go about this, but that should be a pretty straightforward and clear way to do it.

You can check if the user input equals a string with str(user_input) == '*'.
To print it off in reverse, you could print off the last value of the string repeatedly with print(my_list[:-1]) or use my_list.pop() to take and remove the last value.
I would change around your current code to:
my_list = []
while True:
user_input = int(input())
if str(user_input) == '*':
for num in my_list:
print(my_list.pop())
break
else
my_list.append(int(user_input))

Related

Python: Display all even numbers between two integers inclusive, with a limit the number of times the code accepts input

Link to question: https://www.spoj.com/UTPEST22/problems/UTP_Q2/
From what I understand, the question is divided into 2 parts:
Input
The first input is an integer that limits the number of time the user can provide a set of integers.
From the second line onwards, the user provides the sequence of integers up until the specified limit.
The set of integers are arranged in ascending order, separated only by a space each.
Output
For each sequence of integers, the integers in it are looped over. Only those that are even are printed as outputs horizontally.
from sys import stdin
for x in range(1, 1+ int(input())):
# number of cases, number of times the user is allowed to provide input
for line in stdin:
num_list = line.split()
# remove the space in between the integers
num = [eval(i) for i in num_list]
# change the list of numbers into integers each
for numbers in range(num[0], num[-1] + 1):
# the first integer is the lower bound
# the second the upper bound
if numbers % 2 == 0:
# modulo operation to check whether are the integers fully divisible
print(numbers, end = ' ')
# print only the even numbers, horizantally
Can anyone please provide some insights on how to make changes to my code, specifically the loop. I felt so messed up with it. Screenshot of the result.
Any help will be appreciated.
You can use restructure the code into the following steps:
Read each case. You can use the input function here. A list comprehension can be used to read each line, split it into the lower and upper bound and then convert these to integers.
Process each case. Use the lower and upper bounds to display the even numbers in that range.
Using loops: Here is an example solution that is similar to your attempt:
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
for val in range(case[0], case[1] + 1):
if val % 2 == 0:
print(val, end=' ')
print()
This will produce the following desired output:
4 6 8 10 12 14 16 18 20
2 4 6 8 10 12 14 16
-4 -2 0 2 4 6
100 102 104 106 108
Simplify using unpacking: You can simplify this further by unpacking range. You can learn more about unpacking here.
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
lower = case[0] if case[0] % 2 == 0 else case[0]
print(*range(lower, case[1] + 1, 2))
Simplify using bit-wise operators: You can simplify this further using the bit-wise & operator. You can learn more about this operator here.
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
print(*range(case[0] + (case[0] & 1), case[1] + 1, 2))
So first of obviously ask user to input the range however many times they specified, you can just split the input and then just get the first and second item of that list that split will return, by using tuple unpacking, then append to the ranges list the range user inputted but as a Python range object so that you can later easier iterate over it.
After everything's inputted, iterate over that ranges list and then over each range and only print out the even numbers, then call print again to move to a new line in console and done.
ranges = []
for _ in range(int(input())):
start, end = input().split()
ranges.append(range(int(start), int(end) + 1))
for r in ranges:
for number in r:
if number % 2 == 0:
print(number, end="")
print()
Here's my solution:
n = int(input())
my_list = []
for i in range(n):
new_line = input().split()
new_line = [int(x) for x in new_line]
my_list.append(new_line)
for i in my_list:
new_string = ""
for j in range(i[0], i[1]+1):
if (not(j % 2)): new_string += f"{j} "
print(new_string)
Read the first value from stdin using input(). Convert to an integer and create a for loop based on that value.
Read a line from stdin using input(). Assumption is that there will be two whitespace delimited tokens per line each of which represents an integer.
Which gives us:
N = int(input()) # number of inputs
for _ in range(N):
line = input()
lo, hi = map(int, line.split())
print(*range(lo+(lo&1), hi+1, 2))
There are a few issues here but I'm guessing this is what's happening: you run the code, you enter the first two lines of input (4, followed by 3 20) and the code doesn't print anything so you press Enter again and then you get the results printed, but you also get the error.
Here is what's actually happening:
You enter the input and the program prints everything as you expect but, you can't see it. Because for some reason when you use sys.stdin then print without a new line, stdout does not flush. I found this similar issue with this (Doing print("Enter text: ", end="") sys.stdin.readline() does not work properly in Python-3).
Then when you hit Enter again, you're basically sending your program a new input line which contains nothing (equivalent to string of ""). Then you try to split that string which is fine (it will just give you an empty list) and then try to get the first element of that list by calling num[0] but there are no elements in the list so it raises the error you see.
So you can fix that issue by changing your print statement to print(numbers, end = ' ', flush=True). This will force Python to show you what you have printed in terminal. If you still try to Enter and send more empty lines, however, you will still get the same error. You can fix that by putting an if inside your for loop and check if line == "" then do nothing.
There is still an issue with your program though. You are not printing new lines after each line of output. You print all of the numbers then you should go to the newline and print the answer for the next line of input. That can be fixed by putting a print() outside the for loop for numbers in range(num[0], num[-1] + 1):.
That brings us to the more important part of this answer: how could you have figured this out by yourself? Here's how:
Put logs in your code. This is especially important when solving this type of problems on SPOJ, Codeforces, etc. So when your program is doing that weird thing, the first thing you should do is to print your variables before the line of the error to see what their value is. That would probably give you a clue. Equally important: when your program didn't show you your output and you pressed Enter again out of confusion, you should've gotten curious about why it didn't print it. Because according to your program logic it should have; so there already was a problem there.
And finally some side notes:
I wouldn't use eval like that. What you want there is int not eval and it's just by accident that it's working in the same way.
We usually put comments above the line not below.
Since it appears you're doing competitive programming, I would suggest using input() and print() instead of stdin and stdout to avoid the confusions like this one.
SPOJ and other competitive programming websites read your stdout completely independent of the output. That means, if you forget to put that empty print() statement and don't print new lines, your program would look fine in your terminal because you would press Enter before giving the next input line but in reality, you are sending the new line to the stdin and SPOJ will only read stdout section, which does not have a new line. I would suggest actually submitting this code without the new line to see what I mean, then add the new line.
In my opinion, the variable numbers does not have a good name in your code. numbers imply a list of values but it's only holding one number.
Your first if does not need to start from 1 and go to the number does it? It only needs to iterate that many times so you may as well save yourself some code and write range(int(input())).
In the same for loop, you don't really care about the value of variable x - it's just a counter. A standard practice in these situations is that you put _ as your variable. That will imply that the value of this variable doesn't really matter, it's just a counter. So it would look like this: for _ in range(int(input())).
I know some of these are really extra to what you asked for, but I figured you're learning programming and trying to compete in contests so thought give some more suggestions. I hope it helped.
Steps for simple solution
# taking input (number of rows) inside outer loop
# l = lower limit, u = upper limit, taking from user, then converting into integer using map function
# applying logic for even number
# finally printing the even number in single line
for j in range(int(input())):
l, u = map(int, input('lower limit , upper limit').split())
for i in range(l, u+1):
if i%2 == 0: # logic for even number
print(i, end=' ')

Palindrome Coding issue

Writing a program:
Input string from the user
print out whether this string is a palindrome or not
Also, I found a few other codes online but want to work with this code only.m Please let me know the error
i = str(input())
for item in i:
print(item)
if int(i[item]) == int(i[-item]):
print('yes')
else:
print('no')
Use a String slice (The i[::-1] will reverse the string):
i = input()
if i == i[::-1]:
print("Yes")
else:
print("No")
This will take the input from the user and compare it against the same input in reverse.
try this:
word="TOT"
i=word[::-1]
if i==word:
print("palandrom")
Although for item in i: loops through every character in the string, there are several problems with your code line if int(i[item]) == int(i[-item]):. First of all, item is going to be a character from your string. So if the user types "hello", then i[item] first looks for i['h']. Since 'h' is a character and not a number, this makes Python think that i is a dictionary and not a string, and thus tells Python to look for a dictionary named i and return the value where the key is h. That won't work since i is your original string, not a dictionary.
It looks like what you meant to do here is compare i[0] (the first character in the string) to i[-1] (the last character in the string), then i[1] to i[-2], and so on. But even you if looped through the position numbers, i[-item] doesn't mathematically give you what you want.
Yet another issue here is that you're checking each character one at a time and returning "yes" or "no". What you ultimately want though is to output one simple answer: whether your string is a palindrome or not.
Also, there's no need to put str() around input(), since input returns a string anyway, even if the user enters only numerals. By the way, even though you're using i as your string variable, the usual convention in programming is to use i to denote some sort of integer, such as one you're iterating through in a for loop. But that's OK for now.
As some of the other answers have shown, i[::-1] is a quick way to return the reverse of a string itself. So if you're OK with seeing the output return True if the string is a palindrome and False if it isn't, then here's an extremely simple way to do it:
i = input()
print(i == i[::-1])
If the string i is identical to itself reversed, then i == i[::-1] returns True. If not, it returns False. The print statement then prints whichever the answer is.
However, if you really do want to do it the long way, testing character by character in a loop, then here's one way to do it. You could make a function that takes in a string and does the work:
def is_palindrome(mystring):
# The "//2" here divides by 2 and ignores the remainder. So if
# there are an even number of letters, we'll test each pair. If
# It's an odd number, then we don't care about the middle character
# anyway. Compare [0] to [-1], then [1] to [-2], [2] to [-3], and so on.
for position in range(0, len(mystring)//2):
# If we've found a mismatched pair of letters, then we can
# stop looking; we know it's not a palindrome.
if mystring[position] != mystring[(-1 * position) - 1]:
print("This is NOT a palindrome")
return # This breaks you out of the entire function.
# If we've gotten this far, then the word must be a palindrome.
print("This is a palindrome")
# Here's where we run the command to input the string, and run the function
mystring = input("Enter your string: ")
is_palindrome(mystring)

when assigning to a variable list index out of range?

n = int(input())
numb = input()
lis = list(map(int, numb.split()))
lis.sort()
a = lis[n]
for i in (0,len(lis)):
if lis[i]=[a]
print (lis[i-1])
I tried this and when I enter input of 5 for n and the lis as 24689 it says there is an error in the line where a=lis[n] saying the list index is out of range.
The problem is probably with the line
for i in (0,len(lis)):
Lists are zero-based so the valid indexes are from 0 to len(lis) - 1. len(lis) is indeed out of range.
Also, notice that the above line of code means that i will receive only 2 values - 0 and len(lis). Is that what you really mean? If you meant to go over all the indexes, you will need to do
for i in range(len(lis)):
range(n) is an iterator that returns the values from 0 to n - 1.
There are several problems with this code. Firstly, you need to change your for statement to for i in range(0, len(lis)) because you're not currently calling the range function.
Also, on the first iteration, it will try to access index -1, which is the last element in the list. A better idea is to change your range function to range(0, len(lis) - 1), and changing the print statement on the last line to print(lis[i]) to fix the problem of receiving the last element by using the index -1.
P.S. Welcome to Stack Overflow!
Wow, Keep note that what you thought would happen on your third line wasn't the case and is 1 of the 2 problems of your error message. and that 1 problem was due to one single function you used which I have sequentially demonstration below;
I assume you were expecting each character of the string '24689' to be transformed to an integer by the map() function*, then converted to a list by the list() function*, then stored in the Variable ...lis... for later further usage. You were expecting something like [2,4,6,8,9] as Lis`.
Well you almost had that if not for your decision to use split() on Numb.
The Split function will run first and turn the '24689' into a
different iterable, in this case changing '24689' to a list ['24689'].
Then the map() will map every item in this iterable ['24689'] to an
integer. In this case only 1 item exist in the list which is '24689'.
So it maps that item as an integer.
Then the list() function stores this single item which is now an
integer in a list owned by the variable Lis. So you finally get
[24689]. And this is different from your [2,4,6,8,9] expectation.
As I've demonstrated above, so the cause of all this problem was your decision to use Split().
if you take away the split(), then;
the map() will no longer see just one Item but rather '2' '4' '6' '8'
'9' because a string '24689' is an iterable, with 5 individual items in
your case. So the map() runs over all these 5 items in your Numb string and
maps/transforms them to individual integers respectively. Then finally
the List() would have stored all these beautiful individual integers
in a list Owned by the variable Lis.And you get your desired [2,4,6,8,9] in return for the Variable Lis.
So the correct statement for that very line is:
lis = list(map(int, numb)) // This line should now produce [2,4,6,8,9]
The second problem of your error was the value you assigned to the index variable 'n' of list[n]. I assume you wanted to fetch the fifth item in the list. This 'n' is the linear count of items(in your case the individual numbers - 2,4,6,8,9). This counting start from 0 for the first letter instead of 1. Normally when you count items, the first letter is 1 but for index count in python list[n], the first letter is 0 instead of 1 so in your case the fifth item will be indexed as 4 since index count start from 0. So your 'n' input should be 4
These 2 solutions above solves your the specific error you mentioned.
BUT aside from your question above, your entire code will still run into another error even if the above solutions are implemented. This is Due to errors on these following lines as well:
On line 6:
for i in (0,len(lis)): //Wrong due to NO function name called before '(0, len(lis))'.
We will logically assume you want to use the range function
correct expression on LINE 6 is:
for i in range(0, len(lis)):
On Line 7:
if lis[i]=[a] //Three problems on this line...
First, you can't compare two objects with the operator '='. instead use '=='
Second, [a] is a meaningless value in your expression... Does comparing that to a number look right to you? I bet No. Remember [a] is not the same as the variable 'a'.
a = lis[n], while [a] = [lis[n]]
So the correct expression there should be 'a' and not '[a]'
Last, you need to add ':' after every "if", "for" or "while" expression..
Here is how LINE 7 should CORRECTLY look like,
if lis[i] == a:
All the above solutions should satisfy your need. So the complete correct code for your script should look like this:
n = int(input())
numb = input()
lis = list(map(int, numb))
lis.sort()
a = lis[n]
for i in range(0,len(lis)):
if lis[i] == a:
print (lis[i-1])

Replacing Odd and Even-indexed characters in a string

How can I replace even and odd-indexed letters in my strings? I'd like to replace odd-indexed characters with uppercased letters and even-indexed characters with lowercased ones.
x=input("Enter String: ")
How can I modify the inputted string?
This sounds a little like a "do my homework for me" post, but I'll help you out, as I need the training myself.
You can do this by breaking down the problem. (As I am quite new with python syntax, I'm gonna assume that the user has already given an input to string x)
Make a loop, or otherwise iterate through the characters of your string
Make sure you have an index number for each character, which increments for each one
Check if the number is even, by using modulus of 2 (%2). This returns the remainder of a number when divided by 2. In the case of even numbers, that will be 0.
If %2 == 0 set letter to lower case, else set letter to upper case.
append letter to new String, which you defined before the loop. You cannot directly alter a single character in a String, because they are immutable. This means that you cannot change the String itself, but you can assign a new String to the variable.
Done. Print and see if it worked.
Code:
x = "seMi Long StRing WiTH COMPLetely RaNDOM CasINg"
result_string = ""
index = 0;
for c in x:
if(index%2 == 0):
result_string += c.lower()
else:
result_string += c.upper()
index+=1
print(result_string)
s=input()
l=[]
s=s.lower()
l=[i.upper() if s.index(i)%2==0 else i for i in s ]
print("".join(l))
x = 'myname'
for item in range(len(x)):
if item%2==0:
print(x[item].upper())
else:
print(x[item].lower())
this is the for loop i was referring to. but the thing with this line of code is that it is specific to the value you have assigned to the variable x where as the function i provided above can take any string value without us having to repeat the code each time.
def myfunc(string):
result=''
for x in range(len(string)):
if x%2==0:
result=result+string[x].upper()
else:
result=result+string[x].lower()
return result
The above is a function for the question you asked.
A non-function for loop might be easier to grasp right now (like you I am very new to Python as well. So for me it was easier to understand the for loop before I got into functions. Look at my next post for the same.

My Python code is only selecting half of a list's contents?

I'm very new to Python, and I'm going through some example projects I found online but I'm stuck on my palindrome checker at the moment.
Right now, my code takes a word as an input, splits it in half, saves each part into separate variables, makes both of the variables lists, and from there it SHOULD reverse the second list so I can compare it to the first, but from what I've gathered trying to fix it, it's only appending half of the selection to the new list.
For example, if I enter "racecar", it'll split it into "race" and "ecar" just fine, but then when I go to reverse "ecar" it only gives me back "['c', 'e']". (Also, if I switch the variables around to reverse the first half, I get the same error)
I've been trying to figure it out for quite a while now and I'm not making any progress so some help would be very much appreciated!
Ninja Edit: If there's an easier way to do this (which I'm sure there is) I'd love to know, but I still want to figure out what I've done wrong in the code I already have so I can try to learn from it
Here's my code so far:
print "Please enter a word you want to check is a palindrome"
input = raw_input('> ')
#Gets lengths of input
full_length = len(input)
split_length = len(input) / 2
#If word has an even length split like this
if full_length % 2 == 0:
first_half = input[0: split_length]
second_half = input[split_length:full_length]
#If word does not have even length split like this
else:
first_half = input[0:split_length+1]
second_half = input[split_length:full_length]
#Make both halves lists
first_half_list = list(first_half)
print first_half_list
second_half_list = list(second_half)
print second_half_list
# Reverse second half
rev_second_half = []
for x in second_half_list:
current_letter = second_half_list[0]
second_half_list.remove(second_half_list[0])
rev_second_half.insert(0, current_letter)
print rev_second_half
"""
#Check to see if both lists are identical
#If they are identical
print "This word is a palindrome!"
#If they are not identical
print "This word is not a palindrome."
"""
And this is the output I get when I enter 'racecar':
racecar
['r','a','c','e']
['e','c','a','r']
['c', 'e']
There's a lot of unnecessary work going on. No need to convert to lists; the interpreter can manage this all for you. No need to manually reverse a string; use slicing. No need to manually declare the indices of the first and last characters in your string; the interpreter knows where they are. Here's a fixed version of the code; you can view a demo at IDE One:
input = 'racecar'
#Gets lengths of input
full_length = len(input)
split_length = len(input) / 2
#If word has an even length split like this
if full_length % 2 == 0:
first_half = input[:split_length]
second_half = input[split_length:]
#If word does not have even length split like this
else:
first_half = input[:split_length+1]
second_half = input[split_length:]
print first_half
print second_half
rev_second_half = second_half[::-1]
print rev_second_half
race
ecar
race
Notice the way that the second half is getting reversed, by using a slice with a negative iteration step? You can just do that once, to your source string, and compare the result to the original. Now you have a one line method to check if a string is a palindrome: input == input[::-1]
A bit more on slicing syntax (you might like to check out this question). input[::-1] is exactly the same as input[0:len(input):-1]. The colons separate the three arguments, which are start : end : step. The first two create a range which includes start and everything between it and end, but not end itself. Not specifying start or end causes the interpreter to assume you mean "use 0" and "use len", respectively. Not specifying step causes an assumption of 1. Using a negative step means "start at end and go backwards by magnitude of step".
If you want to omit arguments and specify a range with a slice, you need to include the colons, so the interpreter can tell which arguments are omitted. For example, input[-1] will return the last element of input, because no colons means you're specifying an index, and negative means "go backwards from the end", so print input[:-1] would yield "raceca" if your input was "racecar".
As for what was going wrong with your code, the problem is in your reversing loop.
for x in second_half_list:
current_letter = second_half_list[0]
second_half_list.remove(second_half_list[0])
rev_second_half.insert(0, current_letter)
You're removing items from the list you're iterating through. Don't do that, it's a great way to cause problems; it's why you're only getting half the list in this case. There's also needless copying going on, though that won't cause incorrect results. Finally, you're not using your iterated variable at all, which is a sure sign of some sort of problem with your loop code. Here, if you fixed the list mutation but continued using second_half_list[0], you'd get that letter repeated len(second_half_list) times. If you really need to actually reverse a list, you can do it like this instead:
for x in second_half_list:
rev_second_half.insert(0, x)
But you should only actually iterate the list if you need some sort of side effects during the iteration. For a pure reversal in python, you want this, which will perform better:
rev_second_half = [reversed(second_half_list)]
To reverse the string (not in place):
rev_second_half = second_half_list[::-1]
To extend:
I'd suggest keeping the halves as strings, as you can then just compare them with:== and the above reversing technique also works on strings.
The reason you're only getting two values is you're mutating your list while you iterate on it -- you just shouldn't do this, if only because it's a pain to reason about. As an example:
In [34]: nums = range(5) # [0, 1, 2, 3, 4]
In [35]: for num in nums:
....: print "num", num
....: print "nums", nums
....: nums.remove(nums[0])
....:
num 0
nums [0, 1, 2, 3, 4]
num 2
nums [1, 2, 3, 4]
num 4
nums [2, 3, 4]
Notice that this only looped three times. The first time through, everything's dandy, but you remove the first element. However, Python's looping logic thinks it has to go to the second item -- but you removed the first item! Does that mean the second item now, or the second item when things started? For Python's internals, it means the second item now -- which is the third item when things started (i.e. the value 2). From there, stuff just snowballs.
The lesson here is don't mutate a list while you iterate on it. Just use the other means for reversing folks have mentioned here.

Categories