The blue points are a scatterplot (x-y points), not "lines"
The question is, how can I detect the x coordinates at which the "lines" end (marked with green arrows)
I think that the coordinates are proportional to powers of 2 (here is the same chart in logarithmic scale)
The red line shows the accumulated number of points. There is not a fall on the point density where the lines end.
The "lines" do not end all at the same x coordinate, and the y coordinates depend on the dataset (not all are at the same scales, so I cannot just hardcode one y coordinate)
Maybe if I could detect the periodicity of the y coordinate, I could group the points by their approximate maximum x value. (note that the minimum y separation is also unknown)
I'm not asking about a particular language but a suggestion for an algorithm. (although I prefer R or python)
I don't even know what tag to use for this question, I welcome comments on the appropriate tags.
Here is a sample file, and here is a snippet from it:
0.000035048,-0.000012875
0.000035107,0.000000060
0.000039995,0.000004888
0.000036120,-0.000003874
0.000036716,0.000000596
0.000037014,0.000000298
0.000038803,0.000001788
0.000039697,0.000000894
0.000039995,0.000000298
0.000041783,0.000001788
0.000039101,-0.000002682
0.000041485,0.000002384
0.000041008,-0.000000477
0.000039995,-0.000001013
0.000040054,0.000000060
0.000040889,0.000000834
0.000041485,0.000000596
0.000044882,0.000003397
0.000044882,0.000000000
0.000047863,0.000002980
0.000045002,-0.000002861
0.000045002,0.000000000
0.000047684,0.000002682
0.000047326,-0.000000358
0.000047207,-0.000000119
0.000047207,0.000000000
0.000047386,0.000000179
0.000047386,0.000000000
0.000047445,0.000000060
0.000047982,0.000000536
0.000048995,0.000001013
0.000050008,0.000001013
0.000053227,0.000003219
0.000054479,0.000001252
0.000054777,0.000000298
0.000053108,-0.000001669
0.000050008,-0.000003099
0.000051796,0.000001788
0.000051618,-0.000000179
0.000052810,0.000001192
0.000052810,0.000000000
0.000051975,-0.000000834
0.000051558,-0.000000417
0.000053465,0.000001907
0.000053406,-0.000000060
0.000053406,0.000000000
0.000053406,0.000000000
0.000052810,-0.000000596
0.000052810,0.000000000
0.000052571,-0.000000238
0.000052571,0.000000000
0.000051975,-0.000000596
0.000050008,-0.000001967
0.000048280,-0.000001729
0.000047445,-0.000000834
0.000047445,0.000000000
0.000047445,0.000000000
0.000047445,0.000000000
0.000049531,0.000002086
0.000049353,-0.000000179
0.000049412,0.000000060
0.000049412,0.000000000
0.000048876,-0.000000536
0.000048518,-0.000000358
0.000047982,-0.000000536
0.000047803,-0.000000179
0.000047803,0.000000000
0.000048935,0.000001132
0.000047743,-0.000001192
0.000047624,-0.000000119
0.000047445,-0.000000179
0.000047147,-0.000000298
0.000046015,-0.000001132
0.000044882,-0.000001132
0.000043213,-0.000001669
0.000039995,-0.000003219
0.000039995,0.000000000
0.000039279,-0.000000715
0.000039995,0.000000715
0.000039995,0.000000000
0.000041008,0.000001013
0.000041068,0.000000060
0.000044882,0.000003815
0.000041544,-0.000003338
0.000041544,0.000000000
0.000043392,0.000001848
0.000042021,-0.000001371
0.000042021,0.000000000
0.000043929,0.000001907
0.000044763,0.000000834
0.000042200,-0.000002563
0.000044465,0.000002265
0.000044465,0.000000000
0.000044465,0.000000000
0.000043511,-0.000000954
0.000043988,0.000000477
0.000043929,-0.000000060
0.000043929,0.000000000
0.000043929,0.000000000
0.000043929,0.000000000
0.000043869,-0.000000060
0.000043809,-0.000000060
0.000043809,0.000000000
0.000045300,0.000001490
0.000045300,0.000000000
0.000045717,0.000000417
0.000045478,-0.000000238
0.000045478,0.000000000
0.000045478,0.000000000
0.000044763,-0.000000715
0.000044763,0.000000000
0.000044465,-0.000000298
0.000042796,-0.000001669
0.000042856,0.000000060
0.000042856,0.000000000
0.000044405,0.000001550
0.000044286,-0.000000119
0.000044286,0.000000000
0.000044286,0.000000000
0.000044286,0.000000000
0.000044405,0.000000119
0.000044465,0.000000060
0.000045478,0.000001013
0.000045478,0.000000000
0.000045419,-0.000000060
0.000045002,-0.000000417
0.000043631,-0.000001371
0.000043631,0.000000000
0.000044882,0.000001252
0.000044882,0.000000000
0.000044823,-0.000000060
0.000044703,-0.000000119
0.000044644,-0.000000060
0.000044644,0.000000000
0.000048399,0.000003755
0.000048161,-0.000000238
0.000048101,-0.000000060
0.000048161,0.000000060
0.000048161,0.000000000
0.000048161,0.000000000
0.000048459,0.000000298
0.000048459,0.000000000
0.000048459,0.000000000
0.000048280,-0.000000179
0.000048280,0.000000000
0.000048459,0.000000179
0.000048280,-0.000000179
0.000047982,-0.000000298
0.000048280,0.000000298
0.000048220,-0.000000060
0.000047982,-0.000000238
0.000047982,0.000000000
0.000047982,0.000000000
0.000048399,0.000000417
0.000048399,0.000000000
0.000048459,0.000000060
0.000048399,-0.000000060
0.000048399,0.000000000
0.000046253,-0.000002146
0.000046194,-0.000000060
0.000047982,0.000001788
0.000048161,0.000000179
0.000048161,0.000000000
0.000048161,0.000000000
0.000047982,-0.000000179
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047088,-0.000000894
0.000047982,0.000000894
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047266,-0.000000715
0.000047982,0.000000715
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000048399,0.000000417
0.000048399,0.000000000
0.000048399,0.000000000
0.000048399,0.000000000
0.000047982,-0.000000417
0.000047982,0.000000000
0.000047266,-0.000000715
0.000047982,0.000000715
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047505,-0.000000477
0.000047505,0.000000000
0.000047982,0.000000477
0.000047982,0.000000000
0.000047982,0.000000000
0.000048339,0.000000358
0.000048339,0.000000000
0.000048399,0.000000060
0.000047803,-0.000000596
0.000048280,0.000000477
0.000048280,0.000000000
0.000048280,0.000000000
0.000048280,0.000000000
0.000048280,0.000000000
0.000048280,0.000000000
0.000048161,-0.000000119
0.000048161,0.000000000
0.000048101,-0.000000060
0.000048101,0.000000000
0.000047922,-0.000000179
0.000047863,-0.000000060
0.000047028,-0.000000834
0.000047028,0.000000000
0.000047982,0.000000954
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047088,-0.000000894
0.000047982,0.000000894
0.000047982,0.000000000
0.000047505,-0.000000477
0.000047922,0.000000417
0.000047505,-0.000000417
0.000047207,-0.000000298
0.000047147,-0.000000060
0.000047207,0.000000060
0.000047088,-0.000000119
0.000047088,0.000000000
0.000047028,-0.000000060
0.000047028,0.000000000
0.000047028,0.000000000
0.000047028,0.000000000
0.000047803,0.000000775
0.000047803,0.000000000
0.000047803,0.000000000
0.000047803,0.000000000
0.000047803,0.000000000
0.000047803,0.000000000
0.000047922,0.000000119
0.000047863,-0.000000060
0.000047863,0.000000000
0.000047863,0.000000000
0.000047922,0.000000060
0.000047922,0.000000000
0.000047922,0.000000000
0.000047863,-0.000000060
0.000047863,0.000000000
0.000047028,-0.000000834
0.000046611,-0.000000417
0.000046611,0.000000000
0.000046611,0.000000000
0.000046611,0.000000000
0.000046611,0.000000000
0.000046611,0.000000000
0.000046015,-0.000000596
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000045002,-0.000001013
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000043869,-0.000001132
0.000043690,-0.000000179
0.000043690,0.000000000
0.000045776,0.000002086
0.000045776,0.000000000
0.000045776,0.000000000
0.000045776,0.000000000
0.000043690,-0.000002086
0.000043690,0.000000000
0.000043690,0.000000000
0.000043750,0.000000060
0.000043750,0.000000000
0.000043690,-0.000000060
0.000045776,0.000002086
0.000045776,0.000000000
0.000045776,0.000000000
0.000045776,0.000000000
0.000045776,0.000000000
0.000045776,0.000000000
0.000045776,0.000000000
0.000045717,-0.000000060
0.000045717,0.000000000
0.000045717,0.000000000
0.000044107,-0.000001609
0.000044107,0.000000000
0.000044107,0.000000000
0.000044107,0.000000000
0.000044107,0.000000000
0.000045776,0.000001669
0.000046015,0.000000238
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000046015,0.000000000
0.000045002,-0.000001013
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000044167,-0.000000834
0.000044167,0.000000000
0.000044167,0.000000000
0.000045300,0.000001132
0.000045300,0.000000000
0.000045300,0.000000000
0.000046790,0.000001490
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046790,0.000000000
0.000046730,-0.000000060
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000046730,0.000000000
0.000045121,-0.000001609
0.000045121,0.000000000
0.000045121,0.000000000
0.000045121,0.000000000
0.000045121,0.000000000
0.000045002,-0.000000119
0.000045002,0.000000000
0.000045002,0.000000000
0.000044644,-0.000000358
0.000043750,-0.000000894
0.000042975,-0.000000775
0.000042796,-0.000000179
0.000042796,0.000000000
0.000042796,0.000000000
0.000042140,-0.000000656
0.000042140,0.000000000
0.000042140,0.000000000
0.000042200,0.000000060
0.000042200,0.000000000
0.000045002,0.000002801
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000042379,-0.000002623
0.000042379,0.000000000
0.000044882,0.000002503
0.000044882,0.000000000
0.000044882,0.000000000
0.000044823,-0.000000060
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044882,0.000000060
0.000044882,0.000000000
0.000044882,0.000000000
0.000044823,-0.000000060
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044823,0.000000000
0.000044882,0.000000060
0.000042677,-0.000002205
0.000042737,0.000000060
0.000044763,0.000002027
0.000044763,0.000000000
0.000044763,0.000000000
0.000043511,-0.000001252
0.000043511,0.000000000
0.000044763,0.000001252
0.000044763,0.000000000
0.000044763,0.000000000
0.000044763,0.000000000
0.000044763,0.000000000
0.000044763,0.000000000
0.000044763,0.000000000
0.000044763,0.000000000
0.000044763,0.000000000
0.000044882,0.000000119
0.000044882,0.000000000
0.000044882,0.000000000
0.000044882,0.000000000
0.000044882,0.000000000
0.000044882,0.000000000
0.000044882,0.000000000
0.000044882,0.000000000
0.000045002,0.000000119
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000046492,0.000001490
0.000046492,0.000000000
0.000047028,0.000000536
0.000047505,0.000000477
0.000047803,0.000000298
0.000047863,0.000000060
0.000047922,0.000000060
0.000047803,-0.000000119
0.000047803,0.000000000
0.000047803,0.000000000
0.000047803,0.000000000
0.000047922,0.000000119
0.000047982,0.000000060
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047982,0.000000000
0.000047803,-0.000000179
0.000047803,0.000000000
0.000047803,0.000000000
0.000047803,0.000000000
0.000047803,0.000000000
0.000045359,-0.000002444
0.000045359,0.000000000
0.000045300,-0.000000060
0.000045359,0.000000060
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000044525,-0.000000834
0.000044525,0.000000000
0.000044525,0.000000000
0.000044525,0.000000000
0.000044525,0.000000000
0.000044525,0.000000000
0.000044525,0.000000000
0.000044525,0.000000000
0.000045359,0.000000834
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000043988,-0.000001371
0.000043988,0.000000000
0.000043988,0.000000000
0.000045359,0.000001371
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000044048,-0.000001311
0.000045359,0.000001311
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000045359,0.000000000
0.000044525,-0.000000834
0.000045121,0.000000596
0.000045121,0.000000000
0.000045121,0.000000000
0.000045121,0.000000000
0.000045121,0.000000000
0.000045121,0.000000000
0.000044048,-0.000001073
0.000043988,-0.000000060
0.000043750,-0.000000238
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043809,0.000000060
0.000044882,0.000001073
0.000044882,0.000000000
0.000044882,0.000000000
0.000044882,0.000000000
0.000043809,-0.000001073
0.000043750,-0.000000060
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043750,0.000000000
0.000043631,-0.000000119
0.000043631,0.000000000
0.000043631,0.000000000
0.000043571,-0.000000060
0.000043631,0.000000060
0.000043631,0.000000000
0.000045359,0.000001729
0.000047028,0.000001669
0.000047028,0.000000000
0.000047028,0.000000000
0.000047028,0.000000000
0.000043988,-0.000003040
0.000045955,0.000001967
0.000045955,0.000000000
0.000045955,0.000000000
0.000045955,0.000000000
0.000045955,0.000000000
0.000045955,0.000000000
0.000045002,-0.000000954
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000045002,0.000000000
0.000044107,-0.000000894
0.000044107,0.000000000
0.000044107,0.000000000
0.000044107,0.000000000
0.000044107,0.000000000
0.000043690,-0.000000417
0.000043690,0.000000000
0.000043690,0.000000000
0.000043690,0.000000000
0.000043690,0.000000000
0.000043690,0.000000000
0.000043690,0.000000000
0.000043690,0.000000000
0.000043690,0.000000000
0.000043988,0.000000298
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
0.000043988,0.000000000
I had a go on analysing the numbers, starting with this Python script:
file = open(r"C:\Users\timok\Downloads\sample_.csv")
d = {}
for line in file:
x, y = map(float, line.split(","))
d[y] = max(x, d.get(y, x))
for y, x in sorted(d.items()):
print(y, x)
This aggregates the data by Y-coordinate, keeping the maximum X-coordinate. This seemed already a good push in the right direction.
Looking at these results, I could see that these coordinates were multiples of a common (small) factor. After playing around, I found that factor to be near 1/16777215, so that allowed me to map the coordinates to integers:
d = {}
c = 16777215
for line in file:
x, y = map(float, line.split(","))
y = round(y*c)
x = round(x*c)
d[y] = max(x, d.get(y, x))
for y, x in sorted(d.items()):
print(y, x)
Looking at the Y-values around 0, the output is:
...
1 2044
2 4096
3 2050
4 8192
5 2052
6 4100
7 2039
8 16384
9 1991
10 4104
11 2041
12 8200
13 1896
14 4108
15 2011
16 32768
...
And here we see the pattern arise: where Y is a power of 2, the corresponding maximum X coordinate is also a power of 2 and also doubling each time. We see a little noise on the first value (2044 instead of 2048), but the next few values are powers of 2:
...
1 2044
2 4096
4 8192
8 16384
16 32768
...
Looking further, we see this pattern:
The (mapped) X-coordinate is 211+z, where z represents the number of trailing zeroes that the (mapped) Y-coordinate has in its binary representation. So:
y
binary
z
x = 211+z
1
00001
0
2048
2
00010
1
4096
3
00011
0
2048
4
00100
2
8192
5
00101
0
2048
6
00110
1
4096
7
00111
0
2048
8
01000
3
16384
9
01001
0
2048
10
01010
1
4096
11
01011
0
2048
12
01100
2
8192
13
01101
0
2048
14
01110
1
4096
15
01111
0
2048
16
10000
4
32768
So the boundary values you were looking for are 211+z for any natural number z. But this is after we did the mapping. So without the mapping, we get:
211+z / 16777215
This question already has answers here:
Leading zeros for Int in Swift
(12 answers)
Closed 7 years ago.
I want a date as 07:05 or 16:25
I tried but it does not work exactly
var array1 = ["05:30","05:50","06:10","06:30","06:50","07:05","07:13","07:19","07:25","07:30","07:35","07:40","07:46","07:53","07:59","08:06","08:12","08:20","08:28","08:37","08:46","08:55","09:05","09:15","09:25","09:35","09:45","09:55","10:05","10:15","10:25","10:35","10:45","10:55","11:05","11:15","11:25","11:35","11:45","11:55","12:05"]
var arrr = [String()]
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
let calendar = NSCalendar.currentCalendar()
for ora in array1 {
var date = dateFormatter.dateFromString(ora)
var comp = calendar.components((.CalendarUnitHour | .CalendarUnitMinute), fromDate: date!)
var hour = comp.hour
var minute = comp.minute
minute = minute + 10
if minute >= 60 {
minute = minute - 60
hour = hour + 1
}
var nuovoOrario = "\(hour):\(minute)"
arrr.append(nuovoOrario)
}
println(arrr)
the result:
[, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45, 7:50, 7:56, 8:3, 8:9, 8:16, 8:22, 8:30, 8:38, 8:47, 8:56, 9:5, 9:15, 9:25, 9:35, 9:45, 9:55, 10:5, 10:15, 10:25, 10:35, 10:45, 10:55, 1K1:5, 11:15, 11:25, 11:35, 11:45, 11:55, 12:5, 12:15, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45, 5:40, 6:0, 6:20, 6:40, 7:0, 7:15, 7:23, 7:29, 7:35, 7:40, 7:45]
The dates do not have the 0 before it
example
8:3 -> I want 08:03
7:0 -> I want 07:00
10:5-> I want 10:05
just need to comp.minute += 10.
the detail:
var array1 = ["05:30","05:50","06:10","06:30","06:50","07:05","07:13","07:19","07:25","07:30","07:35","07:40","07:46","07:53","07:59","08:06","08:12","08:20","08:28","08:37","08:46","08:55","09:05","09:15","09:25","09:35","09:45","09:55","10:05","10:15","10:25","10:35","10:45","10:55","11:05","11:15","11:25","11:35","11:45","11:55","12:05"]
var arrr = [String()]
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
let calendar = NSCalendar.currentCalendar()
for ora in array1 {
var date = dateFormatter.dateFromString(ora)
var comp = calendar.components((.CalendarUnitHour | .CalendarUnitMinute), fromDate: date!)
comp.minute = comp.minute + 10
var newDate = calendar.dateFromComponents(comp)
var dateString = dateFormatter.stringFromDate(newDate!)
arrr.append(dateString)
}
println(arrr)
As the other poster said, why not use your already created date formatter to create the output strings?
var array1 =
["05:30","05:50","06:10","06:30","06:50","07:05","07:13","07:19",
"07:25","07:30","07:35","07:40","07:46","07:53","07:59","08:06",
"08:12","08:20","08:28","08:37","08:46","08:55","09:05","09:15",
"09:25","09:35","09:45","09:55","10:05","10:15","10:25","10:35",
"10:45","10:55","11:05","11:15","11:25","11:35","11:45","11:55",
"12:05"]
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
for aString in array1
{
if let aDate = dateFormatter.dateFromString(aString)
{
println("date = \(dateFormatter.stringFromDate(aDate))")
}
}
If you want to do math on your dates, you are better off converting to NSDate, then using NSCalendar methods like dateByAddingComponents:toDate:options:
That method would let you add hours, minutes, or whatever to your dates and handle all the overflows correctly. Then just output your resulting date using your date formatter's dateFromString method as above.
If you are determined to generate your output strings yourself, you can use the stringWithFormat intializer for String:
let timeString = String(format: "%02d:%02d", hour, minute)
But it is really much better to use NSCalendar to add component values to your dates and then use your date formatter to output them.
The date calculations using NSCalendar will handle the dozens of edge cases correctly (roll-over of hour, roll-over to next day, roll-over to next year, leap years, different calendars, etc, etc.)
The date formatter will handle localization of your output format much more gracefully than you will, especially if you use styles rather than explicit date formats.
I have been trying to install pyffmpeg in Python 2.7 unsuccessfully. I found a package for Python 2.6, but I can't get it to work. So, I have been mulling around with 2.7. I've seen previous post from others on this site, but they have not helped. Does anyone have experience with this. Ultimately, I want to develop an wxPython app that converts video formats. Thanks
Code that I ultimately wrote that worked for me (very rudimentary, but it works ....):
import wx
import os
import sys
import time
import datetime
from wx.lib.delayedresult import startWorker
class dConvert(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'd-Converter', size=(500, 310))
panel = wx.Panel(self, wx.ID_ANY)#Creates a panel over the widget
toolbar = self.CreateToolBar()
toolbar.Realize()
#Setup Menu
#Setting up Menu
menuFile = wx.Menu()
menuFile.Append(1, "&About...")
menuFile.AppendSeparator()
menuFile.Append(2, "E&xit")
menuBar = wx.MenuBar()
menuBar.Append(menuFile, "&File")
panel.SetBackgroundColour('WHITE')
menu2 = wx.Menu()
menu2.Append(5, "&.mpg to dvd", ".mpg to dvd")
menu2.AppendSeparator()
menu2.Append(wx.NewId(), "&Options...", "Options...")
menuBar.Append(menu2, "&DVD")
menu3 = wx.Menu()
menu3.Append(7, "&Audio/Video Trim")
#menu3.AppendSeparator()
menuBar.Append(menu3, "Media")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnAbout, id=1)
self.Bind(wx.EVT_MENU, self.OnQuit, id=2)
self.Bind(wx.EVT_MENU, self.OnDVD, id=5)
self.Bind(wx.EVT_MENU, self.OnMedia, id=7)
#Add icon to frame
iconFile = "dconverter_image.jpg"
icon1 = wx.Icon(iconFile, wx.BITMAP_TYPE_JPEG)
self.SetIcon(icon1)
self.statusbar = self.CreateStatusBar()
self.statusbar.SetStatusText("Convert Audio & Video")
self.statusbar.SetFieldsCount(3)
self.statusbar.SetStatusWidths([200, -2, -2])
#Panel Text
font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
font2 = wx.Font(7, wx.DEFAULT, wx.NORMAL, wx.BOLD)
directory = wx.StaticText(panel, -1, 'Path: c:\\ffmpeg\\bin', (300, 13))
directory.SetFont(font2)
convertfile = wx.StaticText(panel, -1, 'File:', (270, 53))
convertfile.SetFont(font)
convertfile2 = wx.StaticText(panel, -1, 'Format:', (245, 83))
convertfile2.SetFont(font)
convertfile3 = wx.StaticText(panel, -1, 'Quality:', (244, 113))
convertfile3.SetFont(font)
convertfile4 = wx.StaticText(panel, -1, 'Presets:', (239, 143))
convertfile4.SetFont(font)
image_file = 'cd_rom.gif'
bmp1 = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
panel.bitmap1 = wx.StaticBitmap(panel, -1, bmp1, (50, 30))
self.formats1 = []
#Select Media path
os.chdir("c:\\ffmpeg\\bin")
wrkdir = os.getcwd()
filelist = os.listdir(wrkdir)
#self.formats1 = []
for filename in filelist:
(head, filename) = os.path.split(filename)
if filename.endswith(".avi") or filename.endswith(".mp4") or filename.endswith(".mpg") or filename.endswith(".m4A") or filename.endswith(".MTS") or filename.endswith(".flv") or filename.endswith(".mov") or filename.endswith(".mpeg4") or filename.endswith(".mpeg") or filename.endswith(".mpg2") or filename.endswith(".mkv") or filename.endswith(".m4v") or filename.endswith(".wav") or filename.endswith(".mp3"):
self.formats1.append(filename)
self.format_combo1=wx.ComboBox(panel, size=(140, -1),value='Select Media', choices=self.formats1, style=wx.CB_DROPDOWN, pos=(300,50))
self.Bind(wx.EVT_COMBOBOX, self.fileFormats, self.format_combo1)
#Media Formats
self.formats2 = ['Select Format', '.avi','.mpeg','.mp4','.flv','.mov','.m4a','.m4v','.mkv','.mpeg4','.mpg','.mpg2','.mp3','.ogg','.wav','.wma']
self.format_combo2=wx.ComboBox(panel, size=(100, -1),value='Select Format', choices=self.formats2, style=wx.CB_SORT, pos=(300,81))
#Media Quality
self.formats3 = ['-sameq','-qmax']
self.format_combo3=wx.ComboBox(panel, size=(100, -1),value='Select Quality', choices=self.formats3, style=wx.CB_DROPDOWN, pos=(300,111))
#-qmax settings
self.formats4 = ['1','2','3','4','5','6','7','8']
self.format_combo4=wx.ComboBox(panel, size=(30, -1),value='0', choices=self.formats4, style=wx.CB_DROPDOWN, pos=(405,111))
self.format_combo4.Disable()
#Media Quality
self.formats5 = ['Select Preset','video to mp3']
self.format_combo5=wx.ComboBox(panel, size=(100, -1),value='Select Preset', choices=self.formats5, style=wx.CB_DROPDOWN, pos=(300,141))
#Bit rate
self.formats6 = ['128000', '160000', '180000', '192000']
self.format_combo6=wx.ComboBox(panel, size=(47, -1),value='k/bs', choices=self.formats6, style=wx.CB_DROPDOWN, pos=(405,141))
self.format_combo6.Disable()
#Convert Button
self.button = wx.Button(panel, label="Convert", pos=(300, 171), size=(80, 20))
self.Bind(wx.EVT_BUTTON, self.convertButton, self.button)
#Abort Button
self.button2 = wx.Button(panel, label="Abort", pos=(385, 171), size=(80, 20))
self.Bind(wx.EVT_BUTTON, self.OnAbortButton, self.button2)
self.button2.Disable()
#Refresh Button
self.button3 = wx.Button(panel, label="Refresh", pos=(215, 171), size=(80, 20))
self.Bind(wx.EVT_BUTTON, self.file_refresh, self.button3)
#ComboBox Event
self.Bind(wx.EVT_COMBOBOX, self.OncomboBox, self.format_combo3)
self.Bind(wx.EVT_COMBOBOX, self.OncomboBox2, self.format_combo5)
self.Bind(wx.EVT_COMBOBOX, self.OncomboBox3, self.format_combo2)
def file_refresh(self, e):
self.format_combo1.Clear()
os.chdir("c:\\ffmpeg\\bin")
wrkdir = os.getcwd()
filelist = os.listdir(wrkdir)
for m_files in filelist:
if m_files.endswith(".avi") or m_files.endswith(".mp4") or m_files.endswith(".mpg") or m_files.endswith(".m4A") or m_files.endswith(".MTS") or m_files.endswith(".flv") or m_files.endswith(".mov") or m_files.endswith(".mpeg4") or m_files.endswith(".mpeg") or m_files.endswith(".mpg2") or m_files.endswith(".mkv") or m_files.endswith(".m4v") or m_files.endswith(".wav") or m_files.endswith(".mp3"):
self.format_combo1.Append(m_files)
def file_rename(self, f_name):
ts = time.time()
#Capture readable timestamp
st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H-%M-%S')
os.chdir("c:\\ffmpeg\\bin")
wrkdir = os.getcwd()
#get file extenstion from original file
#fileName, fileExtension = os.path.splitext(wrkdir + '\\' + f_name)
#add file extension to timestamp
new_file = st
return new_file
def fileFormats(self, e):
myFormats = {'audio': ('Select Format', '.m4a', '.mp3', '.ogg', '.wav', '.wma'), 'video': ('Select Format', '.avi', '.flv', '.mkv', '.m4v', '.mov', '.mpg', '.mpg2', '.mpeg4', '.mp4', '.mpeg')}
bad_file = ['Media not supported']
myFile = self.format_combo1.GetValue()
f_exten = (x for x in myFormats['audio'] + myFormats['video'] if myFile.endswith(x))
extension = f_exten.next()
if extension in myFormats['audio']:
self.format_combo2.SetItems(myFormats['audio'])
elif extension in myFormats['video']:
self.format_combo2.SetItems(myFormats['video'])
else:
self.format_combo2.SetItems(bad_file)
def OnQuit(self, event):
self.Close(True)
def OnAbout(self, event):
wx.MessageBox("d-Converter 1.0\n\n Developer: D.Monroe\n\nCopyright 2012",
"About d-Converter", wx.OK | wx.ICON_INFORMATION, self)
def OncomboBox(self, e):
quality=self.format_combo3.GetValue()
if quality == '-qmax':
self.format_combo4.Enable()
else:
self.format_combo4.Disable()
def OncomboBox2(self, e):
quality=self.format_combo5.GetValue()
if quality != 'Select Preset':
self.format_combo1.Enable()
self.format_combo2.Disable()
self.format_combo3.Disable()
self.format_combo4.Disable()
self.format_combo6.Enable()
elif quality == 'Select Preset':
self.format_combo1.Enable()
self.format_combo2.Enable()
self.format_combo3.Enable()
self.format_combo4.Disable()
self.format_combo5.Enable()
self.format_combo6.Disable()
elif quality == 'video to mp3':
self.format_combo6.Enable()
self.format_combo2.Disable()
self.format_combo3.Disable()
self.format_combo4.Disable()
def OncomboBox3(self, e):
v_format=self.format_combo2.GetValue()
if v_format != 'Select Format':
self.format_combo1.Enable()
self.format_combo2.Enable()
self.format_combo3.Enable()
self.format_combo4.Enable()
self.format_combo5.Disable()
self.format_combo6.Disable()
elif v_format == 'Select Format':
self.format_combo1.Enable()
self.format_combo2.Enable()
self.format_combo3.Enable()
self.format_combo4.Disable()
self.format_combo5.Enable()
self.format_combo6.Disable()
def OnMedia(self, e):
pass
def OnDVD(self, e):
""" Select a directory to search"""
os.chdir("c:\\ffmpeg\\bin")
wrkdir = os.getcwd()
filelist = os.listdir(wrkdir)
progdir = 'c:\\ffmpeg\\bin\\ffmpeg.exe' + ' -i '
prog_dir = ' -target '
progdir3 = '-dvd -ac 2 '
vid_format = '.mpg'
sampleList = []
for filename in filelist:
(head, filename) = os.path.split(filename)
if filename.endswith(".avi") or filename.endswith(".flv") or filename.endswith(".mpeg") or filename.endswith(".mp4") or filename.endswith(".mov") or filename.endswith(".mpg2"):
sampleList.append(filename)
dlg = wx.SingleChoiceDialog(
self, "Files in c:\\ffmpeg\\bin", 'Select video to convert',
sampleList,
wx.CHOICEDLG_STYLE
)
if dlg.ShowModal() == wx.ID_OK:
cur_item = dlg.GetStringSelection()
s_string = cur_item
#f_string = self.file_rename(s_string)
f_string = s_string.replace(' ', '')
dlg.Destroy()
dlg2 = wx.SingleChoiceDialog(
self, "Files in c:\\ffmpeg\\bin", 'Select video standard ',
["pal", "ntsc"],
wx.CHOICEDLG_STYLE
)
if dlg2.ShowModal() == wx.ID_OK:
cur_item2 = dlg2.GetStringSelection()
s_string2 = cur_item2
self.button.Disable()
self.button2.Enable()
self.format_combo1.Disable()
self.format_combo2.Disable()
self.format_combo3.Disable()
self.format_combo4.Disable()
self.format_combo5.Disable()
self.format_combo6.Disable()
startWorker(self.LongTaskDone, self.LongTask4, wargs=(progdir, wrkdir, prog_dir, progdir3, f_string, s_string2, vid_format))
dlg2.Destroy()
def convertButton(self, e):
unit1 = self.format_combo1.GetValue()
unit2 = self.format_combo2.GetValue()
unit3 = self.format_combo3.GetValue()
unit4 = None
unit5 = self.format_combo5.GetValue()
bitRate = self.format_combo6.GetValue()
unit6 = bitRate
if unit3 == '-qmax':
unit4 = self.format_combo4.GetValue()
else:
pass
os.chdir("c:\\ffmpeg\\bin")
wrkdir = os.getcwd()
newfile = unit1
#stripped = os.path.splitext(newfile)[0] # Updated 9/26/2013 to strip extension.
#stripped = newfile.strip('mpeg3kaviovfl4w2c.') #Strips the extension from the original file name
stripped = self.file_rename(newfile)
#os.rename(newfile, newfile_f)
progname='c:\\ffmpeg\\bin\\ffmpeg.exe' + ' -i '
preset1_a='-vn -ar 44100 -ac 2 -ab'
preset1_b='-f mp3 '
preset_mp3='.mp3'
if (unit1 == 'Select Media' or unit1 == ''):
amsg = wx.MessageDialog(None, 'You must select a media file!', 'Media Converter', wx.ICON_INFORMATION)
amsg.ShowModal()
amsg.Destroy()
elif (unit1 != 'Select Media' or unit1 != '') and (unit5 == 'Select Preset'):
if (unit2 == 'Select Format' or unit2 == ''):
amsg = wx.MessageDialog(None, 'You must select a format', 'Media Converter', wx.ICON_INFORMATION)
amsg.ShowModal()
amsg.Destroy()
self.format_combo3.Enable()
self.format_combo4.Enable()
self.format_combo5.Enable()
else:
pass
if (unit3 == 'Select Quality' or unit3 == ''):
amsg = wx.MessageDialog(None, 'You must select quality', 'Media Converter', wx.ICON_INFORMATION)
amsg.ShowModal()
amsg.Destroy()
elif (unit3 == '-qmax'):
if (unit4 == '0' or unit4 == ''):
amsg = wx.MessageDialog(None, 'You must select number between 1-8.', 'Media Converter', wx.ICON_INFORMATION)
amsg.ShowModal()
amsg.Destroy()
else:
self.button.Disable()
self.button2.Enable()
pass
else:
self.button.Disable()
self.button2.Enable()
self.format_combo1.Disable()
self.format_combo2.Disable()
self.format_combo3.Disable()
self.format_combo4.Disable()
startWorker(self.LongTaskDone, self.LongTask, wargs=(progname,wrkdir,unit1,unit3,stripped,unit2))
elif (unit1 != 'Select Media' or unit1 != '') and (unit5 == 'video to mp3'):
if unit6 == 'k/bs' or unit6 == None:
amsg = wx.MessageDialog(None, 'You must select a bit rate.', 'Media Converter', wx.ICON_INFORMATION)
amsg.ShowModal()
amsg.Destroy()
else:
self.button.Disable()
self.button2.Enable()
self.format_combo1.Disable()
self.format_combo2.Disable()
self.format_combo3.Disable()
self.format_combo4.Disable()
self.format_combo5.Disable()
self.format_combo6.Disable()
startWorker(self.LongTaskDone, self.LongTask3, wargs=(progname, wrkdir, unit1, preset1_a, unit6, preset1_b, stripped, preset_mp3))
def LongTask(self, progname, wrkdir, unit1, unit3, stripped, unit2):
convert_file1 = progname + wrkdir + '\\' + unit1 + ' ' + unit3 + ' ' + stripped + unit2
self.statusbar.SetStatusText("Converting: " + unit1 + "...")
os.system(convert_file1)
print convert_file1
def LongTask2(self, progname, wrkdir, unit1, unit3, unit4, stripped, unit2):
convert_file2 = progname + wrkdir + '\\' + unit1 + ' ' + unit3 + ' ' + unit4 + ' ' + stripped + unit2
self.statusbar.SetStatusText("Converting: " + unit1 + "...")
os.system(convert_file2)
def LongTask3(self, progname, wrkdir, unit1, preset1_a, unit6, preset1_b, stripped, preset_mp3):
convert_file3 = progname + wrkdir + '\\' + unit1 + ' ' + preset1_a + ' ' + unit6 + ' ' + preset1_b + stripped + preset_mp3
self.statusbar.SetStatusText("Converting: " + unit1 + "...")
os.system(convert_file3)
def LongTask4(self, progdir, wrkdir, prog_dir, progdir3, f_string, s_string2, vid_format):
#convert_file4 = progdir + wrkdir + '\\' + s_string + prog_dir + s_string2 + progdir3 + s_string.strip('mpegaviw24ofl.') + vid_format
convert_file4 = progdir + f_string + prog_dir + s_string2 + progdir3 + f_string.strip('mpegaviw24ofl.') + vid_format
self.statusbar.SetStatusText("Converting: " + f_string + "...")
os.system(convert_file4)
print convert_file4
def LongTaskDone(self, result):
r = result.get()
if r:
amsg = wx.MessageDialog(None, 'Aborted!', 'Media Converter', wx.ICON_INFORMATION)
self.statusbar.SetStatusText("Convert Aborted ...")
amsg.ShowModal()
amsg.Destroy()
self.LongTask.terminate()
else:
self.statusbar.SetStatusText("Done ...")
emsg = wx.MessageDialog(None, 'Finished Converting!', 'Media Converter', wx.ICON_INFORMATION)
emsg.ShowModal()
emsg.Destroy()
self.format_combo1.Enable()
self.format_combo2.Enable()
self.format_combo3.Enable()
self.format_combo5.Enable()
self.format_combo4.Disable()
self.format_combo6.Disable()
self.button.Enable()
self.button2.Disable()
self.shouldAbort = False
"""self.progress_bar.SetValue(0)
self.progress_bar.Hide()"""
def OnAbortButton(self, e):
endprogram = 'c:\\Windows\\System32\\taskkill /IM cmd.exe'
os.system(endprogram)
self.format_combo1.Enable()
self.format_combo2.Enable()
self.format_combo3.Enable()
self.format_combo5.Enable()
self.button.Enable()
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = dConvert()
frame.SetSizeHints(500,310,500,310)
frame.Show()
app.MainLoop()
Since this has no proper answer, I'd like to form one. Unfortunately pyffmpeg wrapper was not able to perform video encoding. So as a solution I suggest you some alternative python wrappers which is capable of our need to encode the videos.
Python Video Converter
FFmpegWrapper
FFVideo
Apart from these you can use full FFmpeg functionality by using python subprocess module to execute full FFmpeg commands. Also with that you can create your own wrapper if you need to. Here Zulko describes a nice way of using subprocess with FFmpeg. Sometimes you will get some confusing events like this when using subprocess. But always there is a solution!
Hope this helps some one with same problem using pyffmpeg to encode videos!