I have a problem with an output in Python
I'm trying to have an input in the form
2
1 10
2 20
2 being the number of tests and each line representing the number used by the function
To be able to have a single output, I'm storing the values in a tab in Python. The problem is that my tab doesn't have the correct values. Using the values given before, I have the following result when looking into the tab
1 2 20 5
Here's my code, thanks :
nbTest = input()
Tab = range(1,2*nbTest + 2)
for i in range(1,nbTest + 1):
a,b = map(int,sys.stdin.readline().split())
Tab[i] = a
Tab[i+1] = b
i = i + 1
print Tab[1], Tab[2], Tab[3], Tab[4]
First you don't have to "initialize" a list in python, so
Tab = range(1,2*nbTest + 2)
is unnecessary.
Second: the line
i = i + 1
doesn't do anything since the variable i is reassigned immediately afterwards.
Third: You should append tuples of values to your output list like this:
nbTest = int(raw_input())
inputs = []
for i in range(0,nbTest):
a,b = map(int, raw_input().split())
inputs.append((a,b))
print nbTest
for el in inputs:
print el[0], el[1]
Your should not modify the loop variable i inside the loop.
The line i = i + 1 does nothing since i is reassigned by the for loop, so you overwrite the Tab[i+1] of the previous iteration with Tab[i]. If you want i to increase by 2 at each iteration use range(1, nbTest+1, 2) instead.
Also note that you don't have to initialise the size of your list, you can simply do Tab=list(), and then use Tab += [a,b]
Also, pythons arrays start at 0, so your range must be start from 0 as well. Otherwise the first slot of the list will not be replaced.
Note If you are using python3, you must do Tab = list(range(1, 2*nbTest+2)) if you want Tab to be a list.
Related
I tried to generate the longest sequence of equal numbers in python, but it doesn't work
def lista_egale(lst1 = input("numbers go here ")):
l = 0
lst1 = []
maxi = -9999
prev_one = None
lmax = -9999
for current in lst1:
if prev_one == current:
l += 1
else:
l = 1
if l > lmax:
lmax = l
maxi = current
prev_one = current
print("longest sequence is ", lmax, " and ", maxi)
lista_egale()
Input:
1 2 2 2 2 3 4 5 6 2 2 2
Expected Output:
longest sequence is 4 and 2
I was going to write up the same concern about your default argument, but that would at least work correctly the first time it is called. This function does not. Everyone jumped on that common problem, and failed to notice the next line. Let's look another look at this abridged version of your code:
irrelevant = input("numbers go here ")
def lista_egale(lst1 = irrelevant):
# while it is true that your default argument is bad,
# that doesn't matter because of this next line:
lst1 = []
for current in lst1:
# unreachable code
pass
To clarify, since your reply indicates this is not clear enough, it doesn't matter what value was passed in to lst1 if you immediately overwrite it with an empty list.
(for others reading this:) Separating out what I labeled "irrelevant" is not quite identical, but I'm trying to point out that the input was overwritten.
I don't think this function should take user input or have a default argument at all. Let it be a function with one job, and just pass it the data to work on. User input can be collected elsewhere.
Based on Barmar's note, and the principle of using only unmutable default values, your code should look something more like this:
def lista_egale(inp1 = None):
if not inp1:
inp1 = input("numbers go here ")
# optionally do some error checking for nonnumerical characters here
lst1 = [int(i) for i in inp1.split(" ")]
# rest of your code here
lista_egale()
Basically, input returns a string value, and you need to convert it into a list of integers first before you start working on it.
You can swap out the list comprehension for map(int, inp1.split(" ")) as it will do the same (but you can't iterate through a map more than once unless you wrap it in a list() function first).
Secondly, avoid setting mutable default arguments as (in short) can lead to weird results when rerunning the same function multiple times.
I am making a program where I can fix the sequence of a list, the sequence is to be followed with a difference of 2. In this program if the difference is less than 2 I need to replace/change a certain number. Well, I have done most of the part but the problem is I can't replace it properly, and since I can't change the number in the process my output also comes out wrong.
list_1 = [1,2,5]
for i in range(1, len(list_1)):
htl = list_1[i]-list_1[i-1]
if not htl == 2:
list_1[i-1] += 2
print(list_1[i-1])
The output is:
3
4
But it's wrong, the correct ouput is:
3
Because I only need to change the number 2 to 3 to make it a correct sequence.
What I am doing in my code is that, I am subtracting backwards to spot the differences. If there is a difference, I am trying to add 2 to number it is being subtracted from, and then change the number that is being subtracted. But in my program I am having problem in replacing. For example(the subtraction starts from index 1 - index 0, index 2 - index 1 and it goes on): 2-1 = 1 so it's not clearly following the sequence, and I am trying to replace the 2 in 'list_1' with 3(by adding 2 to the number that index 1 is being subtracted from). I can't replace the number and since I can't replace that,the next output comes that shouldn't be there because only one change is needed.
My way may be really tangled up, but it was the best I could think of, if there is a faster way I would really appreciate the help. But otherwise I did like to fix my Code, where the general idea is to follow the sequence of 2.
The attribution is wrong:
list_1 = [1,2,5]
for i in range(1, len(list_1)):
htl = list_1[i]-list_1[i-1]
if htl != 2:
list_1[i] = list_1[i-1] + 2
print (list_1)
Output:
[1, 3, 5]
But in the end, what you want is simply a sequence starting at an initial point and with a step of 2 and with a certain number of points
start = 1
points = 3
stop = points * 2 + start
list_1 = list(range(start, stop, 2))
Output:
Out[11]: [1, 3, 5]
Less than 2?
I also think you were changing the -1 list value rather than the current index.
This should work?
list_1 = [1,2,5,6,7,8,15]
for i in range(1, len(list_1)):
htl = list_1[i]-list_1[i-1]
if htl < 2:
list_1[i] =list_1[i-1]+2
print(list_1[i-1])
print(list_1)
If i understand your explanation, you wish to convert
list_1 = [1,2,5] to list_1 = [1,3,5]
The line which is not giving the desired result is:
list_1[i-1] += 2
The first time the for loop iterates, it generates list_1 = [3,2,5].
The second time it iterates, it generates list_1 = [3,4,5].
Change the line:
list_1[i-1] += 2
to:
list_1[i] = list_1[i-1] + 2
Update:
You said if the difference is less than 2, you wish to make the change.
Consider changing the if not htl ==2: condition to if htl < 2. This will then catch the situation where you have two consecutive elements which are equal. It also reads better.
Update 2:
In order to catch an error where your list has only zero or one elements, I recommend you place a condition before the loop. if len(list_1) > 1: would be a good place to start, otherwise the indexing will raise an IndexError.
I'm not sure to have totally understand what you want to do but first, to fixe you output probleme change :
list_1[i-1] += 2
by
list_1[i-1] += 2
and put your print outside of the for like that :
for i in range(1, len(list_1)):
htl = list_1[i]-list_1[i-1]
if not htl == 2:
list_1[i-1] += 1
print(list_1[i-1])
print(list_1[i-1])
Hope that can help you.
Here's issue I am learning python newly i want to use loop for generating inputs from user which are then operated for some custom function (say Lcm or squaring them and returning ) so how to perform code
Consider
k,l=0,0
while l>=10:
n_k=input("Enter")
k=k+1
l=l+1
#Do something within for loop
#here problem begins
#lets say i am dividing each variable by c which is here in for loop
for c in range(somevalue,0,-1):
now how should i operate the variables clearly i have no intention writting n_0%c ,n_1%c etc
Any Help???
Instead of n_k being a single variable i think you want n to be a list. A list is just a bunch of variables stored together. For example the code:
n = [1, 4, 2]
print(n[0]) #0th element of the list
print(n[1]) #1st element of the list
print(n[2]) #2nd element of the list
outputs
1
4
2
the line n = [1, 4, 2] is just defining the list. The elements of the list are accessed using the n[index] notation.
In python you can also add elements to a list at any time using the append statement. To illustrate let's define an empty list and add some elements to it.
n = []
n.append(8)
Now if we try
print(n[0])
the code will print 8.
So let's say we wanted to square a list of numbers we receive from user input, we would write
n = []
k = 0
num_inputs = 10
while k < num_inputs:
n.append(input("Enter:"))
k = k + 1
k = 0
while k < num_inputs:
print(n[k] * n[k])
k = k + 1
Hope it helps.
I want to know if is it possible to change the value of the iterator in its for-loop?
For example I want to write a program to calculate prime factor of a number in the below way :
def primeFactors(number):
for i in range(2,number+1):
if (number%i==0)
print(i,end=',')
number=number/i
i=i-1 #to check that factor again!
My question : Is it possible to change the last two line in a way that when I change i and number in the if block, their value change in the for loop!
Update: Defining the iterator as a global variable, could help me? Why?
Short answer (like Daniel Roseman's): No
Long answer: No, but this does what you want:
def redo_range(start, end):
while start < end:
start += 1
redo = (yield start)
if redo:
start -= 2
redone_5 = False
r = redo_range(2, 10)
for i in r:
print(i)
if i == 5 and not redone_5:
r.send(True)
redone_5 = True
Output:
3
4
5
5
6
7
8
9
10
As you can see, 5 gets repeated. It used a generator function which allows the last value of the index variable to be repeated. There are simpler methods (while loops, list of values to check, etc.) but this one matches you code the closest.
No.
Python's for loop is like other languages' foreach loops. Your i variable is not a counter, it is the value of each element in a list, in this case the list of numbers between 2 and number+1. Even if you changed the value, that would not change what was the next element in that list.
The standard way of dealing with this is to completely exhaust the divisions by i in the body of the for loop itself:
def primeFactors(number):
for i in range(2,number+1):
while number % i == 0:
print(i, end=',')
number /= i
It's slightly more efficient to do the division and remainder in one step:
def primeFactors(number):
for i in range(2, number+1):
while True:
q, r = divmod(number, i)
if r != 0:
break
print(i, end=',')
number = q
The only way to change the next value yielded is to somehow tell the iterable what the next value to yield should be. With a lot of standard iterables, this isn't possible. however, you can do it with a specially coded generator:
def crazy_iter(iterable):
iterable = iter(iterable)
for item in iterable:
sent = yield item
if sent is not None:
yield None # Return value of `iterable.send(...)`
yield sent
num = 10
iterable = crazy_iter(range(2, 11))
for i in iterable:
if not num%i:
print i
num /= i
if i > 2:
iterable.send(i-1)
I would definitely not argue that this is easier to read than the equivalent while loop, but it does demonstrate sending stuff to a generator which may gain your team points at your next local programming trivia night.
It is not possible the way you are doing it. The for loop variable can be changed inside each loop iteration, like this:
for a in range (1, 6):
print a
a = a + 1
print a
print
The resulting output is:
1
2
2
3
3
4
4
5
5
6
It does get modified inside each for loop iteration.
The reason for the behavior displayed by Python's for loop is that, at the beginning of each iteration, the for loop variable is assinged the next unused value from the specified iterator. Therefore, whatever changes you make to the for loop variable get effectively destroyed at the beginning of each iteration.
To achieve what I think you may be needing, you should probably use a while loop, providing your own counter variable, your own increment code and any special case modifications for it you may need inside your loop. Example:
a = 1
while a <= 5:
print a
if a == 3:
a = a + 1
a = a + 1
print a
print
The resulting output is:
1
2
2
3
3
5
5
6
Yes, we can only if we dont change the reference of the object that we are using. If we can edit the number by accessing the reference of number variable, then what you asked is possible.
A simple example:
a=[1,2,3]
a=a+[4]==>here, a new object is created which plots to different address.
a+=[4]==>here , the same object is getting updated which give us the desired result.
number=10
list1=list(range(2,number+1))
# list1
for i in list1:
print(list1,i)
if (number%i==0):
print(i,end=',')
number=number//i #we can simply replace it with number//=i to edit the number without changing the reference or without creating a new object.
try:
[list1.pop() for i in range(10,0,-1) if(i>number)]
#here pop() method is working on the same object which list created by number refers. so, we can able to change the iterable in the forloop.
except:
continue
i=i-1 #to check that factor again!
Basically, I need to make my program able to create multiple (unlimited) variables for me, that I will still be able to use manipulate through my code, without me defining them.
I was thinking to have a letter and a number as the variable name, such as a1, and have the program create new variables just adding 1 to the number. So it would create a1 through a30 or so. How would I do this?
My program is going to add polynomials and the variables (or list now) is to separate the different monomials, and since I don't know how many monomials there will be in the polynomial, I needed a way to make the number flexible so I have an exact amout of spaces for the monomials, no extras, and no less.
Here's the code:
# Sample polynomial set to x, the real code will say x = (raw_input("Enter a Polynomial")).
x = '(5xx + 2y + 2xy)+ (4xx - 1xy)'
# Isdigit command set to 't' to make the code easier to write.
t = str.isdigit
# Defining v for later use.
v = 0
# Defining 'b' which will be the index number that the program will look at.
b = 1
# Creating 'r' to parse the input to whatever letter is next.
r = x [b]
# Defining n which will be used later to tell if the character is numeric.
n = 0
# Defining r1 which will hold one of the monomials, ( **will be replaced with a list**)
#This was the variable in question.
r1 = ''
# Setting 'p' to evaluate if R is numeric ( R and T explained above).
p = t(r)
# Setting 'n' to 1 or 0 to replace having to write True or False later.
if p == True:
n = 1
else:
n = 0
# Checking if r is one of the normal letters used in Algebra, and adding it to a variable
if r == 'x':
v = 'x'
c = 1
elif r == 'y':
v = 'y'
c = 1
elif r == 'z':
v = 'z'
c = 1
# If the character is a digit, set c to 0, meaning that the program has not found a letter yet (will be used later in the code).
elif n == 1:
v = r
c = 0
# Adding what the letter has found to a variable (will be replaced with a list).
r1 = r1 + v
b = b + 1
I will eventually make this a loop.
I added comments to the code so it's more understandable.
Essentially, you are trying to programmatically, dynamically modify the heap space where the variables live. I really do not think this is possible. If it is, it is very obscure.
I do understand where you are coming from. When I was first learning to program I had thought to solve problems in ways that would require such "dynamically created" variables. The solution really is to recognize what kind of (collection) data structure fits your needs.
If you want variables a1 through a30, create a list a. Then a1 would be a[1], a30 would be a[30]. It is a little different to write, but it should give you the behavior you need.
I spent at least five minutes trying to think why you would want to do this in the first place, until I decided I could actually write the code in less than five minutes, and hoping that in return you'd tell us why you want to do this.
Here's the code:
def new(value):
highest = -1
for name in globals():
if name.startswith('a'):
try:
number = int(name[1:])
except:
continue
if number > highest:
highest = number
globals()['a%d' % (highest + 1, )] = value
new("zero")
new("one")
new("two")
print a2 # prints two