slices to the rescue :)
def left(s, amount):
return s[:amount]
def right(s, amount):
return s[-amount:]
def mid(s, offset, amount):
return s[offset:offset+amount]
Answer from Andy W on Stack Overflowslices to the rescue :)
def left(s, amount):
return s[:amount]
def right(s, amount):
return s[-amount:]
def mid(s, offset, amount):
return s[offset:offset+amount]
If I remember my QBasic, right, left and mid do something like this:
>>> s = '123456789'
>>> s[-2:]
'89'
>>> s[:2]
'12'
>>> s[4:6]
'56'
http://www.angelfire.com/scifi/nightcode/prglang/qbasic/function/strings/left_right.html
Videos
You're looking for slicing:
>>> s = "Hello World!"
>>> print s[2:] # From the second (third) letter, print the whole string
llo World!
>>> print s[2:5] # Print from the second (third) letter to the fifth string
llo
>>> print s[-2:] # Print from right to left
d!
>>> print s[::2] # Print every second letter
HloWrd
So for your example:
>>> s = 'col555'
>>> print s[3:]
555
If you know it will always be col followed by some numbers:
>>> int('col1234'[3:])
1234
You'd mask the resulting value, with & bitwise AND:
mask = 2 ** 16 - 1
k = (i << j) & mask
Here 16 is your desired bit width; you could use i.bit_length() to limit it to the minimum required size of i, but that'd mean that any left shift would drop bits.
The mask forms a series of 1 bits the same width as the original value; the & operation sets any bits to 0 outside of these:
>>> 0b1010 & 0b111
2
>>> format(0b1010 & 0b111, '04b')
'0010'
Some side notes:
- You are left shifting, not right shifting.
You appear to have forgotten to a
din your debug print:print "%d left shift %d gives" % (i,j)There was a lone
%there that combined with thegforgivesto make%g(floating point formatting).You can use:
def showbits(x): return format(x, '016b')to format an integer to a 0-padded 16-character wide binary representation without the
0bprefix.
Because Python does some magic to prevent this condition, known as an overflow, from happening. It does this by adjusting the type:
>>> i = 5225
>>> type(i)
<type 'int'>
>>> j = i << 16; type(j); bin(j)
<type 'int'>
'0b10100011010010000000000000000'
>>> j = i << 32; type(j); bin(j)
<type 'int'>
'0b101000110100100000000000000000000000000000000'
>>> j = i << 64; type(j); bin(j)
<type 'long'>
'0b10100011010010000000000000000000000000000000000000000000000000000000000000000'
>>> j = i << 128; type(j); bin(j)
<type 'long'>
'0b101000110100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
If you want to limit the bits you want to work with, do as Martijn suggests and use a 16-bit mask.
>>> j = 0xffff & (i << 12); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'1001000000000000'
>>> j = 0xffff & (i << 13); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'0010000000000000'
>>> j = 0xffff & (i << 14); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'0100000000000000'
>>> j = 0xffff & (i << 15); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'1000000000000000'
>>> j = 0xffff & (i << 16); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'0000000000000000'
this code will work. I assume you already have a function got getting links. I have just used a dummy one _get_links.
You will have to delete the content of links file and need to put 0 in index file after every successful run.
import time
def _get_links():
return ["a", "b", "c"]
def _get_links_from_file():
with open("links") as file:
return file.read().split(",")
def _do_something(link):
print(link)
time.sleep(30)
def _save_links_to_file(links):
with open("links", "w") as file:
file.write(",".join(links))
print("links saved")
def _save_index_to_file(index):
with open("index", "w") as file:
file.write(str(index))
print("index saved")
def _get_index_from_file():
with open("index",) as file:
return int(file.read().strip())
def process_links():
links=_get_links_from_file()
if len(links) == 0:
links = _get_links()
_save_links_to_file(links)
else:
links = _get_links_from_file()[_get_index_from_file():]
for index, link in enumerate(links):
_do_something(link)
_save_index_to_file(index+1)
if __name__ == '__main__':
process_links()
I would suggest that you write out the links to a file along with a date/time stamp of the last time it was processed. When you write links to the file, you will want to make sure that you don't write the same link twice. You will also want to date/time stamp a link after you are done processing it.
Once you have this list, when the script is started you read the entire list and start processing links that haven't been processed in X days (or whatever your criteria is).
Steps:
- Load links file
- Scrape links from sitemap, compare to existing links from file, write any new links to file
- Find the first link that hasn't been processed in X days
Process that link then write date/time stamp next to link, e.g.
http://www.google.com,1/25/2019 12:00PM- Go back to Step 3
Now any time you kill the run, the process will pick up where you left off.
NOTE: Just writing out the date may be enough. It just depends on how often you want to refresh your list (hourly, etc.) or if you want that much detail.
Starting with bisect, one use (as shown here) is to find an index into one list that can be used to dereference a related list:
from bisect import bisect
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect(breakpoints, score)
return grades[i]
grades = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
print(grades)
Output:
['F', 'A', 'C', 'C', 'B', 'A', 'A']
bisect_left operates the same way as bisect but in the case of a "tie" it will return the index to the "left" of the match (e.g., a score of 70 in the above example would map to "D" using bisect_left)
Bisect maintains a list in sorted order. If you insert an item into the list, the list still maintains its order.
Since your list is already sorted, bisect.bisect_left([1,2,3], 2) will insert the item 2 after 2 in your list (since the item 2 is already present in list).
You can find more about the "bisect" module here:
https://docs.python.org/3/library/bisect.html
First two letters for each value in a column:
>>> df['StateInitial'] = df['state'].str[:2]
>>> df
pop state year StateInitial
0 1.5 Auckland 2000 Au
1 1.7 Otago 2001 Ot
2 3.6 Wellington 2002 We
3 2.4 Dunedin 2001 Du
4 2.9 Hamilton 2002 Ha
For last two that would be df['state'].str[-2:]. Don't know what exactly you want for middle, but you can apply arbitrary function to a column with apply method:
>>> df['state'].apply(lambda x: x[len(x)/2-1:len(x)/2+1])
0 kl
1 ta
2 in
3 ne
4 il
With regards to the mid, probably a short cut code would be:
df['state'].str[3:5]
this will start from the 3rd character and give you the 3rd and 4th character of the string.