Write a loop using python - python

I need to print value with some size using condition.
size, url
1 https://api-glb-ams.smoot.apple.com/user_guid?
3257 https://init.itunes.apple.com/WebObjects/MZInit.woa/wa/signSapSetupCert
0 http://engine.rbc.medialand.ru/code?
35 http://www.google-analytics.com/collect?
0 http://engine.rbc.medialand.ru/test?
0 http://engine.rbc.medialand.ru/code?
I get it in loop and I try to get all url, where size more than 43.
if not size:
continue
elif size[0] < 43:
continue
else:
print size[0], url
If condition works, but elif doesn't. It print all size and url

In Python 2, which you are using, strings can be compared to integers. Strings always compare as being larger than integers.
>>> '35' < 43
False
To solve this, wrap the string in an int() call:
>>> int('35') < 43
True
For your program:
elif int(size[0]) < 43:

Related

This code seems to never reach the solution even though it doesn't go into an infinite loop

I wanted to solve the Knight's Tour and came up with the following program. It never gives a solution (even given 2 hours of time) even though it doesn't seem to be getting into an infinite loop anywhere.
I tried it with a 4x4 board (with one space filled) as I knew the solution to it and the code gave the right solution without any problems.
from __future__ import print_function
The recursive function which implements the backtracking algorithm:
def moveKnight(boolBoard, i, j, moveNo, previousMoves):
if moveNo == 63:
previousMoves.pop(0)
print('Success! The moves of the brave Knight are:')
for i in previousMoves:
print(i, end = '\t')
return True
possMoves = possibleMoves(boolBoard, i, j)
for nextMove in possMoves:
previousMoves.append(nextMove)
boolBoard[nextMove[0]][nextMove[1]] = False
if moveKnight(boolBoard, nextMove[0], nextMove[1], moveNo+1, previousMoves):
return True
previousMoves.remove(nextMove)
boolBoard[nextMove[0]][nextMove[1]] = True
return False
Function for finding out all possible moves of the knight given its position and the board:
def possibleMoves(boolBoard, posr, posc):
possMoves = [[]]
if posr + 2 < 8 and posc + 1 < 8:
if boolBoard[posr+2][posc+1]:
possMoves.append([posr+2, posc+1])
if posr+2 < 8 and posc - 1 >= 0:
if boolBoard[posr+2][posc-1]:
possMoves.append([posr+2, posc-1])
if posr+1 < 8 and posc + 2 < 8:
if boolBoard[posr+1][posc+2]:
possMoves.append([posr+1, posc+2])
if posr-1 >= 0 and posc+2 < 8:
if boolBoard[posr-1][posc+2]:
possMoves.append([posr-1, posc+2])
if posr-2>=0 and posc + 1 < 8:
if boolBoard[posr-2][posc+1]:
possMoves.append([posr-2, posc+1])
if posr - 2 >= 0 and posc - 1 >= 0:
if boolBoard[posr-2][posc-1]:
possMoves.append([posr-2, posc-1])
if posr - 1 >= 0 and posc - 2 >= 0:
if boolBoard[posr-1][posc-2]:
possMoves.append([posr-1, posc-2])
if posr + 1 < 8 and posc - 2 >= 0:
if boolBoard[posr+1][posc-2]:
possMoves.append([posr+1, posc-2])
possMoves.pop(0)
return possMoves
Main Function:
if __name__ == '__main__':
boolBoard = [[True]*8]*8
for i in range(0, 8):
boolBoard[i] = [True, True, True, True, True, True, True, True]
previousMoves = [[]]
boolBoard[0][0] = False
if not moveKnight(boolBoard, 0, 0, 0, previousMoves):
print('Not Possible Bro...')
I tried to run your code on my laptop (not really powerful configuration) for different chessboard dimensions:
5x5: 2000 possible tours (0.11s)
6x6: 7 millions possible tours (29s)
8x8: 19,000,000 billions possible tours (expected execution time: 2.5 billion years)
Your code seems to work like a charm but there's simply too many possibilities to try out.
Hope it helped.
I used modified version of you program at it worked for 8x8 , starting at position 0,4 (since I knew there is valid solution for that) and it took around 2 minute.
Following are changes I did
Initialize Move No at 2, Since First move is done by setting first piece
Increase MoveNo checking to 65
I also modified sequence to check possible values staring at col+2, row+1 and doing clock wise

List index is out of range - but I'm checking the length before processing

Wonder if you can advise - I get the below error when processing a list of items. I should note, that this script works for 99% of items - as I've expanded the list now to 84M rows, I am now getting this issue.
I do this for each line
elif len(str(x)) > 3 and str(x[len(x)-2]).rstrip() in cdns:
So, I don't see how the index can be out of range, if I'm actively checking if it's over a certain length before processing?
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-2-a28be4b396bd> in <module>()
21 elif len(str(x)) > 4 and str(x[len(x)-2]).rstrip() in cdns:
22 cleandomain.append(str(x[len(x)-3])+'.'+str(x[len(x)-2])+'.'+str(x[len(x)-1]))
---> 23 elif len(str(x)) > 5 and str(x[len(x)-3]).rstrip() in cdns:
24 cleandomain.append(str(x[len(x)-4])+'.'+str(x[len(x)-3])+'.'+str(x[len(x)-2])+'.'+ str(x[len(x)-1]))
25 #if its in the TLD list, do this
IndexError: list index out of range
The full loop is below, so I'd expect that if the index list item was out of range, that it'd just carry out the other command & print the list value?
for x in index:
#if it ends with a number, it's an IP
if str(x)[-1].isnumeric():
cleandomain.append(str(x[0])+'.'+str(x[1])+'.*.*')
#if its in the CDN list, take a subdomain as well
elif len(str(x)) > 3 and str(x[len(x)-2]).rstrip() in cdns:
cleandomain.append(str(x[len(x)-3])+'.'+str(x[len(x)-2])+'.'+str(x[len(x)-1]))
elif len(str(x)) > 4 and str(x[len(x)-3]).rstrip() in cdns:
cleandomain.append(str(x[len(x)-4])+'.'+str(x[len(x)-3])+'.'+str(x[len(x)-2])+'.'+ str(x[len(x)-1]))
#if its in the TLD list, do this
elif len(str(x)) > 3 and str(x[len(x)-2]).rstrip()+'.'+ str(x[len(x)-1]).rstrip() in tld:
cleandomain.append(str(x[len(x)-3])+'.'+str(x[len(x)-2])+'.'+ str(x[len(x)-1]))
elif len(str(x)) > 2 and str(x[len(x)-1]) in tld:
cleandomain.append(str(x[len(x)-2])+'.'+ str(x[len(x)-1]))
#if its not in the TLD list, do this
else:
cleandomain.append(x)
X is generated as below:
X is a list of lists - the split out parts of a domain like below
[['news', 'bbc', 'co', 'uk'], ['graph', 'facebook', 'com']]
import pandas as pd
path = "Desktop/domx.csv"
df = pd.read_csv(path, delimiter=',', header='infer', encoding = "ISO-8859-1")
df2 = df[((df['domain'] != '----'))]
df3 = df2[['domain', 'use']]
for row in df2.iterrows():
index = df3.domain.str.split('.').tolist()
Any help would be great
Let me expand on what Corentin Limier said in comments with a specific counterexample, since you categorically deny this could be true, without actually checking your debugger:
based on your original question error dump:
---> 23 elif len(str(x)) > 5 and str(x[len(x)-3]).rstrip() in cdns:
IndexError: list index out of range
x = ['counterexample']
print ('x =', x)
print ('length of x is', len(x))
print ('length of str(x) is', len(str(x)))
if len(str(x)) > 5:
print ('You think this is safe')
try:
x[len(x)-3]
except IndexError:
print ('but it is not.')
x = ['counterexample']
length of x is 1
length of str(x) is 18
You think this is safe
but it is not.
You need to know if the index is valid, compared to the number of items in x. You are actually looking at the length of the string representation of x, which is completely different. The string is 18 characters long, but there is only one item in the list.
PS: Don't feel bad, we have ALL done this. By this, I mean "get blinders when we have written code completely different from what we thought we did." This is one of the primary reasons for "code review" in professional settings.

Creating new column by looping through another column...not working

I'm trying to create a new "category" based on the value in another column (looping through that column). Here is my code.
def minority_category(minority_col):
for i in minority_col:
if i <= 25:
return '<= 25%'
if i > 25 and i <= 50:
return '<= 50%'
if i > 50 and i <= 75:
return '<= 75%'
if i > 75 and i <= 100:
return '<= 100%'
return 'Unknown'
However, the result is '<=75%' in the entire new column. Based on examples I've seen, my code looks right. Can anyone point out something wrong with the code? Thank you.

How to group a list of numbers into certain categories

I am trying to figure out how to take in a list of numbers and sort them into certain categories such as 0-10, 10-20, 20-30 and up to 90-100 but I have the code started, but the code isn't reading in all the inputs, but only the last one and repeating it. I am stumped, anyone help please?
def eScores(Scores):
count0 = 0
count10 = 0
count20 = 0
count30 = 0
count40 = 0
count50 = 0
count60 = 0
count70 = 0
count80 = 0
count90 = 0
if Scores > 90:
count90 = count90 + 1
if Scores > 80:
count80 = count80 + 1
if Scores > 70:
count70 = count70 + 1
if Scores > 60:
count60 = count60 + 1
if Scores > 50:
count50 = count50 + 1
if Scores > 40:
count40 = count40 + 1
if Scores > 30:
count30 = count30 + 1
if Scores > 20:
count20 = count20 + 1
if Scores > 10:
count10 = count10 + 1
if Scores <= 10:
count0 = count0 + 1
print count90,'had a score of (90 - 100]'
print count80,'had a score of (80 - 90]'
print count70,'had a score of (70 - 80]'
print count60,'had a score of (60 - 70]'
print count50,'had a score of (50 - 60]'
print count40,'had a score of (40 - 50]'
print count30,'had a score of (30 - 40]'
print count20,'had a score of (20 - 30]'
print count10,'had a score of (10 - 20]'
print count0,'had a score of (0 - 10]'
return eScores(Scores)
Each time eScores is called is sets all the counters (count10, count20) back to zero. So only the final call has any effect.
You should either declare the counters as global variables, or put the function into a class and make the counters member variables of the class.
Another problem is that the function calls itself in the return statement:
return eScores(Scores)
Since this function is (as I understand it) supposed to update the counter variables only, it does not need to return anything, let alone call itself recursively. You'd better remove the return statement.
One thing you're making a mistake on is that you're not breaking out of the whole set of if's when you go through. For example, if you're number is 93 it is going to set count90 to 1, then go on to count80 and set that to one as well, and so on until it gets to count10.
Your code is repeating because the function is infintely recursive (it has no stop condition). Here are the relevant bits:
def eScores(Scores):
# ...
return eScores(Scores)
I think what you'd want is more like:
def eScores(Scores):
# same as before, but change the last line:
return
Since you're printing the results, I assume you don't want to return the values of score10, score20, etc.
Also, the function won't accumulate results since you're creating new local counts each time the function is called.
Why don't you just use each number as a key (after processing) and return a dictionary of values?
def eScores(Scores):
return_dict = {}
for score in Scores:
keyval = int(score/10)*10 # py3k automatically does float division
if keyval not in return_dict:
return_dict[keyval] = 1
else:
return_dict[keyval] += 1
return return_dict

Strange logic with bool

I can't understand one thing with logic in python. Here is the code:
maxCounter = 1500
localCounter = 0
while True:
print str(localCounter) + ' >= ' + str(maxCounter)
print localCounter >= maxCounter
if localCounter >= maxCounter:
break
localCounter += 30
And the result output:
...
1440 >= 1500
False
1470 >= 1500
False
1500 >= 1500
False
1530 >= 1500
False
1560 >= 1500
False
...
And I have infinity cycle there. Why?
topPos = someClass.get_element_pos('element')
scrolledHeight = 0
while True:
print str(scrolledHeight) + ' >= ' + str(topPos)
print scrolledHeight >= topPos
if scrolledHeight >= topPos:
print 'break'
break
someClass.run_javascript("window.scrollBy(0, 30)")
scrolledHeight += 30
print scrolledHeight
time.sleep(0.1)
To fix your code try this:
topPos = int(someClass.get_element_pos('element'))
Why?
When I copy and paste your original code I get this:
...
1440 >= 1500
False
1470 >= 1500
False
1500 >= 1500
True
One small change that I can find to make to your code that reproduces the behaviour you are seeing is to change the first line to this:
maxCounter = '1500' # string instead of integer
After making this change I can also see the output you get:
1410 >= 1500
False
1440 >= 1500
False
1470 >= 1500
False
1500 >= 1500
False
1530 >= 1500
False
etc..
The problem seems to be at this line:
topPos = someClass.get_element_pos('element')
This is likely to assign a string to topPos, instead of a numeric variable. You need to convert this string to a numeric variable so you can do a numeric comparison against it.
topPos = int(someClass.get_element_pos('element'))
Otherwise, e.g. in CPython implementation of v2.7, any int is always going to compare less than any string.
Related questions
How does Python compare string and int?

Categories