Workaround Google Sheets API does not accept range request without specifying desired final line - google-sheets-api

My spreadsheet has values in this model:
And I need to create a list to use in Python, including the empty fields that exist between values:
CLIENT_SECRET_FILE = 'client_secrets.json'
API_NAME = 'sheets'
API_VERSION = 'v4'
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
spreadsheet_id = sheet_id
get_page_id = 'Winning_Margin'
range_score = 'O1:O10000'
spreadsheets_match_score = []
range_names2 = get_page_id + '!' + range_score
result2 = service.spreadsheets().values().get(
spreadsheetId=spreadsheet_id, range=range_names2, valueRenderOption='UNFORMATTED_VALUE').execute()
sheet_output_data2 = result2["values"]
for i, eventao2 in enumerate(sheet_output_data2):
try:
spreadsheets_match_score.append(sheet_output_data2[i][0])
except:
spreadsheets_match_score.append('')
In this case, this list (spreadsheets_match_score = []) would result in:
["0-0","0-0","4-0","0-1","6-0","","","","0-3","2-2","","","","","0-1","","","3-0","1-1","3-1","","","",""]
My spreadsheet currently has 24 rows, but it will grow without a fixed ending value.
So, I tried to use the range without putting the value of the last line (range_score = 'O1:O'), but it doesn't accept, the range needs to specify the final line (range_score = 'O1:O10000').
I put 10000 exactly so I don't have to change, but this is very wrong to do, because it does a search for a non-existent range, I'm very afraid that in the future it will generate an error.
Is there any method so that I can not need to specify the last row of the worksheet?
To be something like:
range_score = 'O1:O'

The problem is not in the range specification method for data collection, can use either range_score = 'O1:O' or range_score = 'O1:O100000000000' if looking for all the column rows.
In the case of the question, the problem was when line 1 of the desired column has no values, being null, the request failed but because of the empty ["values"] return.
In short, I was looking for the error in the wrong place.

Related

How do I reverse each value in a column bit wise for a hex number?

I have a dataframe which has a column called hexa which has hex values like this. They are of dtype object.
hexa
0 00802259AA8D6204
1 00802259AA7F4504
2 00802259AA8D5A04
I would like to remove the first and last bits and reverse the values bitwise as follows:
hexa-rev
0 628DAA592280
1 457FAA592280
2 5A8DAA592280
Please help
I'll show you the complete solution up here and then explain its parts below:
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
list_of_bits = [i+j for i, j in zip(trimmed_bits[::2], trimmed_bits[1::2])]
reversed_bits = [list_of_bits[-i] for i in range(1,len(list_of_bits)+1)]
return ''.join(reversed_bits)
df['hexa-rev'] = df['hexa'].apply(lambda x: reverse_bits(x))
There are possibly a couple ways of doing it, but this way should solve your problem. The general strategy will be defining a function and then using the apply() method to apply it to all values in the column. It should look something like this:
df['hexa-rev'] = df['hexa'].apply(lambda x: reverse_bits(x))
Now we need to define the function we're going to apply to it. Breaking it down into its parts, we strip the first and last bit by indexing. Because of how negative indexes work, this will eliminate the first and last bit, regardless of the size. Your result is a list of characters that we will join together after processing.
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
The second line iterates through the list of characters, matches the first and second character of each bit together, and then concatenates them into a single string representing the bit.
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
list_of_bits = [i+j for i, j in zip(trimmed_bits[::2], trimmed_bits[1::2])]
The second to last line returns the list you just made in reverse order. Lastly, the function returns a single string of bits.
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
list_of_bits = [i+j for i, j in zip(trimmed_bits[::2], trimmed_bits[1::2])]
reversed_bits = [list_of_bits[-i] for i in range(1,len(list_of_bits)+1)]
return ''.join(reversed_bits)
I explained it in reverse order, but you want to define this function that you want applied to your column, and then use the apply() function to make it happen.

Strange numbers in the output from Netcdf in Fortran

I'm fairly new to Fortran and try reading in 3D (80000*100*10) single precision NetCDF data (however I'd just read it 2D like (80000,100,1st)). I would need to convert them into double precision for some further code not shown below.
The .nc-File which I create to check if the reading/writing works does contain only "0" if I use real single precision for all NF90-functions as well as the variable 'values'.
It does contain mostly "0" and several weird numbers which don't seem to relate in a conceivable way to the input data if I use double precision (code shown below). At least I get any output in my nc file this way.
I don't get any compiling errors {nor error codes in 'STATUS' if I check for specific lines after NF90 functions. Update: That was mistaken}. Input_test.nc gets created exactly as expected regarding dimensions, but not regarding the actual values.
My code is:
PROGRAM read
Implicit None
INCLUDE 'netcdf.inc'
INTEGER :: NCID, horstart, verstart, horlen, verlen, horcount, vercount, STATUS, STATUS2
REAL(kind=8), DIMENSION(80000,100) :: values
horstart = 1
verstart = 1
horcount = 80000 !!(tried to use this instead of horlen, doesn't change anything)
vercount = 100 !!(tried to use this instead of verlen, doesn't change)
varname = 'pres'
!! get input data
STATUS = NF90_OPEN('my_valid_path/file.nc', 0, NCID)
STATUS = NF90_INQ_DIMID(NCID, 'ncells', horid)
STATUS = NF90_INQ_DIMID(NCID, 'height', verid)
STATUS = NF90_INQ_DIMLEN(NCID,horid,horlen)
STATUS = NF90_INQ_DIMLEN(NCID,verid,verlen)
STATUS = NF90_INQ_VARID(NCID,varname,varid)
STATUS = NF90_GET_VARA_DOUBLE(NCID,varid,[horstart,verstart,1],[horlen,verlen,1],values)
STATUS = NF90_CLOSE(NCID)
STATUS = NF90_CREATE ('some_path/input_test.nc', 0, ncid);
STATUS = NF90_DEF_DIM (ncid, 'hor',horcount, dimhor)
STATUS = NF90_DEF_DIM (ncid, 'ver',vercount, dimver)
STATUS = NF90_DEF_DIM (ncid, '1d',1, dimcode)
STATUS = NF90_DEF_VAR(ncid,'pres',NF90_DOUBLE,2,[dimhor,dimver],pres_id)
STATUS = NF90_DEF_VAR(ncid,'status',NF90_INT,1,dimcode,stat_id)
STATUS = NF90_ENDDEF(ncid)
STATUS = NF90_PUT_VARA_DOUBLE(ncid,pres_id,[horstart,verstart],[horcount,vercount],values)
STATUS = NF90_PUT_VARA_INT(ncid,stat_id,1,1,STATUS2)
STATUS = NF90_CLOSE(ncid)
The nc file I read from doesn't contain any zeroes, not even in the 3rd dimension. The Output file however does contain a lot zeroes, it is not empty though.
Example input: 0,095213220 0,099325478 0,10358732 0,10800611 0,11259078 0,11734842 0,12228279 0,12740466 0,13271827 0,13822863 0,14394356
Example output: 0 0 0 0 0 0,000493943283800036 0,000594558776356280 0,000234268474741839 2,88491937681101e-05 2,09666131608306e-16 7,30948746534081e-20
I'm probably doing something stupid, but I went temporarily out of ideas what to check for.
UPDATE: Thoroughly checking the error codes saved in STATUS did give a non-zero match at NF90_GET_VARA_DOUBLE/(also REAL). Getting back to this tomorrow.
With error handler I came to the conclusion that the above code works. The errors eventually came from a spelling mistake of the variables I tried to read from.

Putting dbSendQuery into a function in R

I'm using RJDBC in RStudio to pull a set of data from an Oracle database into R.
After loading the RJDBC package I have the following lines:
drv = JDBC("oracle.jdbc.OracleDriver", classPath="C:/R/ojdbc7.jar", identifier.quote = " ")
conn = dbConnect(drv,"jdbc:oracle:thin:#private_server_info", "804301", "password")
rs = dbSendQuery(conn, statement= paste("LONG SQL QUERY TO SELECT REQUIRED DATA INCLUDING REQUEST FOR VARIABLE x"))
masterdata = fetch(rs, n = -1) # extract all rows
Run through the usual script, they always execute without fail; it can sometimes take a few minutes dependent on variable x, e.g. may result in 100K rows or 1M rows being pulled. masterdata will return everything in a dataframe.
I'm now trying to place all of the above into a function, with one required argument, variable x which is a TEXT argument (a city name); this input however is also part of the LONG SQL QUERY.
The function I wrote called Data_Grab is as follows:
Data_Grab = function(x) {
drv = JDBC("oracle.jdbc.OracleDriver", classPath="C:/R/ojdbc7.jar", identifier.quote = " ")
conn = dbConnect(drv,"jdbc:oracle:thin:#private_server_info", "804301", "password")
rs = dbSendQuery(conn, statement= paste("LONG SQL QUERY TO SELECT REQUIRED DATA,
INCLUDING REQUEST FOR VARIABLE x"))
masterdata = fetch(rs, n = -1) # extract all rows
return (masterdata)
}
My function appears to execute in seconds (no error is produced) however I get just the 21 column headings for the dataframe and the line
<0 rows> (or 0-length row.names)
Not sure what is wrong here; obviously expecting function to still take minutes to execute as data being pulled is large, but not being returned any actual data frame.
Help is appreciated!
if you want to parameterize your query to a JDBC database, try also using the gsubfn package. code might look like this:
library(gsubfn)
library(RJDBC)
Data_Grab = function(x) {
rd1 = x
df <- fn$dbGetQuery(conn,"SELECT BLAH1, BLAH2
FROM TABLENAME
WHERE BLAH1 = '$rd1')
return(df)
basically, you need to put a $ before the variable name that stores the parameter you wish to pass.

Error Handling with Live Data Matlab

I am using a live data API that is returning the next arriving trains. I plan on giving the user the next 5 trains arriving. If there are less than 5 trains arriving, how you handle that? I am having trouble thinking of a way, I was thinking a way with if statements but don't know how I would set them up.
time1Depart = dataReturnedFromLiveAPI{1,1}.orig_departure_time;
time2Depart = dataReturnedFromLiveAPI{1,2}.orig_departure_time;
time3Depart = dataReturnedFromLiveAPI{1,3}.orig_departure_time;
time4Depart = dataReturnedFromLiveAPI{1,4}.orig_departure_time;
time5Depart = dataReturnedFromLiveAPI{1,5}.orig_departure_time;
time1Arrival = dataReturnedFromLiveAPI{1,1}.orig_arrival_time;
time2Arrival = dataReturnedFromLiveAPI{1,2}.orig_arrival_time;
time3Arrival = dataReturnedFromLiveAPI{1,3}.orig_arrival_time;
time4Arrival = dataReturnedFromLiveAPI{1,4}.orig_arrival_time;
time5Arrival = dataReturnedFromLiveAPI{1,5}.orig_arrival_time;
The code right now uses a matrix that goes from 1:numoftrains but I am using just the first five.
It's a bad practice to assign individual value to a separate variable. Better if you pass all related values to a vector or cell array depending on class of orig_departure_time and orig_arrival_time.
It looks like dataReturnedFromLiveAPI is a cell array of structures. Then you can do:
timeDepart = cellfun(#(x), x.orig_departure_time, ...
dataReturnedFromLiveAPI(1,1:min(5,size(dataReturnedFromLiveAPI,2))), ...
'UniformOutput',0 );
timeArrival = cellfun(#(x), x.orig_arrival_time, ...
dataReturnedFromLiveAPI(1,1:min(5,size(dataReturnedFromLiveAPI,2))), ...
'UniformOutput',0 );
Then you how to access the values one by one as
time1Depart = timeDepart{1};
If orig_departure_time and orig_arrival_time are numeric scalars, you can use ...'UniformOutput',1.... You will get output as a vector and can get single values with timeDepart(1).

VB.Net Enum ToString returns an unknown number

I built a simple vb.net winforms project that pings IP addresses and logs the results. It works fine on most machines I've tried it on. I log the status result of the ping (System.Net.NetworkInformation.IPStatus) by using the IPStatus.tostring method.
Normally this returns a text result such as "Success" or "TimedOut"
Yesterday, on one machine it returned "65" ...which is not one of the enum values. I have a feeling it might be a combination of values. I ran some test code:
Dim status As System.Net.NetworkInformation.IPStatus
status = Net.NetworkInformation.IPStatus.Success
MsgBox(status.ToString)
Which returns "Success"
And this:
status = Net.NetworkInformation.IPStatus.BadDestination Or Net.NetworkInformation.IPStatus.BadHeader
MsgBox(status.ToString)
Which returns "11050"
I suspect the "65" I saw was the result of some combination of enum values. Is there any way I can change the code in my second example to show the text names of both values? That is... any way I can see ALL values in this variable?
IPStatus is NOT a Flags enum, therefore it is not appropriate to combine its member values in this way. This is its definition via Reflector:
Public Enum IPStatus
' Fields
BadDestination = &H2B0A
BadHeader = &H2B22
BadOption = &H2AFF
BadRoute = &H2B04
DestinationHostUnreachable = &H2AFB
DestinationNetworkUnreachable = &H2AFA
DestinationPortUnreachable = &H2AFD
DestinationProhibited = &H2AFC
DestinationProtocolUnreachable = &H2AFC
DestinationScopeMismatch = &H2B25
DestinationUnreachable = &H2B20
HardwareError = &H2B00
IcmpError = &H2B24
NoResources = &H2AFE
PacketTooBig = &H2B01
ParameterProblem = &H2B07
SourceQuench = &H2B08
Success = 0
TimedOut = &H2B02
TimeExceeded = &H2B21
TtlExpired = &H2B05
TtlReassemblyTimeExceeded = &H2B06
Unknown = -1
UnrecognizedNextHeader = &H2B23
End Enum
How you are getting an IPStatus value of 65 - now that's the real question :)
Try using System.Enum to get the name of the value.
In your example, use:
MsgBox(System.Enum.GetName(GetType(Net.NetworkInformation.IPStatus), status))
It looks like apart from Success (0) and Unknown (-1), the defined enum values range from 11002 to 11045, so 65 is not a combination of any of the defined enum values.
If you are getting 65 back, you will not be able to resolve this to a string.
That enum is not marked with the FlagsAttribute and therefore should not be or'd together because the result could overlap. You are better off creating your own enum to contain the values you are looking for.
You should be able to loop over the enum's range using something like [1], test whether the current enum bit is represented in the value and add it to a string builder.
I find it hard to write up a working sample in VB.NET in this little text box, but I'm sure someone else will oblige.
[1] http://damieng.com/blog/2008/04/10/using-linq-to-foreach-over-an-enum-in-c