Fail with error 'TransferHelper: TRANSFER_FROM_FAILED' - bsc

I'm trying to create a script to sell token on pancakeswap and cant seem to get it to work.
I'm able to buy just fine but cannot sell.
I'm getting Fail with error 'TransferHelper: TRANSFER_FROM_FAILED'
The script is a hit and miss with the balance of the tokens depending of the decimals. I just wish there was a way that I could put 100% of balance.
pancakeswap2_txn = contract.functions.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenValue, 0, [contract_id, spend],
sender_address,
(int(time.time()) + 1000000)
).buildTransaction({
'from': sender_address,
'gas': 1800000,
'gasPrice': web3.toWei(input("How much Gwei: "), 'gwei'),
'nonce': web3.eth.get_transaction_count(sender_address),
})
signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn, private_key = config.private)
tx_token = web3.eth.send_raw_transaction(signed_txn.rawTransaction)

You just need to enable/approve the tokens you want to swap in PancakeSwap. I did it manually (buy and sell each token to approve.)

Related

Google Ads API: How to Send Batch Requests?

I'm using Google Ads API v11 to upload conversions and adjust conversions.
I send hundreds of conversions each day and want to start sending batch requests instead.
I've followed Google's documentation and I upload/ adjust conversions exactly the way they stated.
https://developers.google.com/google-ads/api/docs/conversions/upload-clicks
https://developers.google.com/google-ads/api/docs/conversions/upload-adjustments
I could not find any good explanation or example on how to send batch requests:
https://developers.google.com/google-ads/api/reference/rpc/v11/BatchJobService
Below is my code, an example of how I adjust hundreds of conversions.
An explanation of how to do so with batch requests would be very appreciated.
# Adjust the conversion value of an existing conversion, via Google Ads API
def adjust_offline_conversion(
client,
customer_id,
conversion_action_id,
gclid,
conversion_date_time,
adjustment_date_time,
restatement_value,
adjustment_type='RESTATEMENT'):
# Check that gclid is valid string else exit the function
if type(gclid) is not str:
return None
# Check if datetime or string, if string make as datetime
if type(conversion_date_time) is str:
conversion_date_time = datetime.strptime(conversion_date_time, '%Y-%m-%d %H:%M:%S')
# Add 1 day forward to conversion time to avoid this error (as explained by Google: "The Offline Conversion cannot happen before the ad click. Add 1-2 days to your conversion time in your upload, or check that the time zone is properly set.")
to_datetime_plus_one = conversion_date_time + timedelta(days=1)
# If time is bigger than now, set as now (it will be enough to avoid the original google error, but to avoid a new error since google does not support future dates that are bigger than now)
to_datetime_plus_one = to_datetime_plus_one if to_datetime_plus_one < datetime.utcnow() else datetime.utcnow()
# We must convert datetime back to string + add time zone suffix (+00:00 or -00:00 this is utc) **in order to work with google ads api**
adjusted_string_date = to_datetime_plus_one.strftime('%Y-%m-%d %H:%M:%S') + "+00:00"
conversion_adjustment_type_enum = client.enums.ConversionAdjustmentTypeEnum
# Determine the adjustment type.
conversion_adjustment_type = conversion_adjustment_type_enum[adjustment_type].value
# Associates conversion adjustments with the existing conversion action.
# The GCLID should have been uploaded before with a conversion
conversion_adjustment = client.get_type("ConversionAdjustment")
conversion_action_service = client.get_service("ConversionActionService")
conversion_adjustment.conversion_action = (
conversion_action_service.conversion_action_path(
customer_id, conversion_action_id
)
)
conversion_adjustment.adjustment_type = conversion_adjustment_type
conversion_adjustment.adjustment_date_time = adjustment_date_time.strftime('%Y-%m-%d %H:%M:%S') + "+00:00"
# Set the Gclid Date
conversion_adjustment.gclid_date_time_pair.gclid = gclid
conversion_adjustment.gclid_date_time_pair.conversion_date_time = adjusted_string_date
# Sets adjusted value for adjustment type RESTATEMENT.
if conversion_adjustment_type == conversion_adjustment_type_enum.RESTATEMENT.value:
conversion_adjustment.restatement_value.adjusted_value = float(restatement_value)
conversion_adjustment_upload_service = client.get_service("ConversionAdjustmentUploadService")
request = client.get_type("UploadConversionAdjustmentsRequest")
request.customer_id = customer_id
request.conversion_adjustments = [conversion_adjustment]
request.partial_failure = True
response = (
conversion_adjustment_upload_service.upload_conversion_adjustments(
request=request,
)
)
conversion_adjustment_result = response.results[0]
print(
f"Uploaded conversion that occurred at "
f'"{conversion_adjustment_result.adjustment_date_time}" '
f"from Gclid "
f'"{conversion_adjustment_result.gclid_date_time_pair.gclid}"'
f' to "{conversion_adjustment_result.conversion_action}"'
)
# Iterate every row (subscriber) and call the "adjust conversion" function for it
df.apply(lambda row: adjust_offline_conversion(client=client
, customer_id=customer_id
, conversion_action_id='xxxxxxx'
, gclid=row['click_id']
, conversion_date_time=row['subscription_time']
, adjustment_date_time=datetime.utcnow()
, restatement_value=row['revenue'])
, axis=1)
I managed to solve it in the following way:
The conversion upload and adjustment are not supported in the Batch Processing, as they are not listed here.
However, it is possible to upload multiple conversions in one request since the conversions[] field (list) could be populated with several conversions, not only a single conversion as I mistakenly thought.
So if you're uploading conversions/ adjusting conversions you can simply upload them in batch this way:
Instead of uploading one conversion:
request.conversions = [conversion]
Upload several:
request.conversions = [conversion_1, conversion_2, conversion_3...]
Going the same way for conversions adjustment upload:
request.conversion_adjustments = [conversion_adjustment_1, conversion_adjustment_2, conversion_adjustment_3...]

Can GA4-API fetch the data from requests made with a combination of minute and region and sessions?

Problem
With UA, I was able to get the number of sessions per region per minute (a combination of minute, region, and sessions), but is this not possible with GA4?
If not, is there any plan to support this in the future?
Detail
I ran GA4 Query Explorer with date, hour, minute, region in Dimensions and sessions in Metrics.
But I got an incompatibility error.
What I tried
I have checked with GA4 Dimensions & Metrics Explorer and confirmed that the combination of minute and region is not possible. (see image below).
(updated 2022/05/16 15:35)Checked by Code Execution
I ran it with ruby.
require "google/analytics/data/v1beta/analytics_data"
require 'pp'
require 'json'
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = '' # service acount file path
client = ::Google::Analytics::Data::V1beta::AnalyticsData::Client.new
LIMIT_SIZE = 1000
offset = 0
loop do
request = Google::Analytics::Data::V1beta::RunReportRequest.new(
property: "properties/xxxxxxxxx",
date_ranges: [
{ start_date: '2022-04-01', end_date: '2022-04-30'}
],
dimensions: %w(date hour minute region).map { |d| { name: d } },
metrics: %w(sessions).map { |m| { name: m } },
keep_empty_rows: false,
offset: offset,
limit: LIMIT_SIZE
)
ret = client.run_report(request)
dimension_headers = ret.dimension_headers.map(&:name)
metric_headers = ret.metric_headers.map(&:name)
puts (dimension_headers + metric_headers).join(',')
ret.rows.each do |row|
puts (row.dimension_values.map(&:value) + row.metric_values.map(&:value)).join(',')
end
offset += LIMIT_SIZE
break if ret.row_count <= offset
end
The result was an error.
3:The dimensions and metrics are incompatible.. debug_error_string:{"created":"#1652681913.393028000","description":"Error received from peer ipv4:172.217.175.234:443","file":"src/core/lib/surface/call.cc","file_line":953,"grpc_message":"The dimensions and metrics are incompatible.","grpc_status":3}
Error in your code, Make sure you use the actual dimension name and not the UI name. The correct name of that dimension is dateHourMinute not Date hour and minute
dimensions: %w(dateHourMinute).map { |d| { name: d } },
The query explore returns this request just fine
results
Limited use for region dimension
The as for region. As the error message states the dimensions and metrics are incompatible. The issue being that dateHourMinute can not be used with region. Switch to date or datehour
at the time of writing this is a beta api. I have sent a message off to google to find out if this is working as intended or if it may be changed.

Check balance of individual accounts in unit tests

I can't figure out how to test the balance of given accounts when writing unit tests.
For example, Bob buys something. He pays 10 NEAR. 3 NEAR should go to alice.near, 7 NEAR should go to bob.near. I want to check if the 3 and the 7 NEAR are there. I'm using VMContext. I tried switching the context, so I can use env::account_balance(), but that will not solve my problem.
let mut context = get_context(600_000_000_000_000_000_000_000); // Alice is person who interacts
testing_env!(context.build());
let mut contract = Contract::new_default_meta(to_valid_account("vault.near"), to_valid_account("carol.near")); // Vault is owner, Carol will be admin
let price = U128(500_000_000_000_000_000_000_000);
contract.mint_root(test_token_metadata(), to_valid_account("carol.near"), price.clone(), None,
Some(HashMap::from([ // Alice: 20%
(to_valid_account("alice.near"), 2000), // Vault: 80%
(to_valid_account("vault.near"), 8000)
]))
);
log!("caller: {:?}", env::current_account_id());
log!("Alice balance: {:?}", env::account_balance());
context.predecessor_account_id(to_valid_account("bob.near")); // Bob interacts with the contract
context.signer_account_id(to_valid_account("bob.near"));
//testing_env!(context.build());
contract.buy_nft_from_vault("fono-root-0-0".to_string());
context.predecessor_account_id(to_valid_account("alice.near")); // Bob interacts with the contract
context.signer_account_id(to_valid_account("alice.near"));
log!("caller: {:?}", env::current_account_id());
log!("Alice balance: {:?}", env::account_balance());
I'm looking for a function that looks something like this: context_get_balance("alice.near"); And it would give me the balance for alice.near in the simulated blockchain. Is it possible to do this somehow? Maybe it is not possible to do this. If not, what is the best approach when writing similar unit tests?

Got Error "Command Get label of interval: not available for current selection" when trying to edit selections with certain labels

I was trying to replace certain selections of sounds with silences, but before I could get into the essential part, the "Get label from interval" command failed before I was able to check whether I'd obtained the correct output.
Error Message I've Got on Praat
I'd thought it was some problems with the toy audio I played with, so I switched to another one but strangely enough, every time I always got stuck with the third interval in the sequence. Screenshot available here:
The Third Interval was Strangely not Available
The code I'm using right now is quite simple as below:
There could be problems with how I process the intervals labelled as "sounding", but it should not be relevant to the error I got here.
----------------------------------------------------------------------------
soundname$ = chooseReadFile$: "Open a sound file"
sound = Read from file: soundname$
gridname$ = chooseReadFile$: "Select the corresponding TextGrid file."
grid = Read from file: gridname$
tier = 1
soundEnd = Get total duration
numOfIntervals = Get number of intervals: tier
writeInfoLine: "Number of Intervals:", numOfIntervals
appendInfoLine: "**** Starting to Replace Selected Sounds... ****"
for interval from 1 to numOfIntervals
appendInfoLine: "Interval#", interval
label$ = Get label of interval: tier, interval
appendInfoLine: "Interval#", interval, ": ", label$
if label$ == "sounding"
startTime = Get starting point: tier, interval
endTime = Get end point: tier, interval
newSilence = Create Sound from formula: "new_silence", 1, startTime, endTime, 44100, ~ 0
before = Extract part: 0, startTime, "rectangular", 1, "no"
after = Extract part: endTime, soundEnd, "rectangular", 1, "no"
selectObject: before, newSilence, after
new = Concatenate
Write to WAV file... "new".wav
removeObject: before, newSilence, after
endif
endfor
appendInfoLine: "Finish!"
----------------------------------------------------------------------------
I'd suspected that it was because of my editing that some shifts occurred in the TextGrid-- however, since I only supplanted the sounds with silences that were of the same length, there should not be impacts on sounds or TextGrids afterwards. However, since I never had the chance to output some playable audio results, all I inferred above could not be corroborated by solid truth.
Thank you all so much for your kind attention and help in advance!

Why is Google Translate API giving me so many 403s?

I've posted the relevant code below. I have a quote of 100 requests / second and a total quota of 50M characters daily (the latter of which I've never hit). I'm including 75 requests in each batch (i.e. in the below, there are 75 strings in each group).
I'm constantly running into 403s, usually after a very short time span of less than a minute of firing off requests. After that, no amount of backoff works until the next day. This is really debilitating and I'm very unsure why it's happening. So far, their response team hasn't been helpful for diagnosing the issue.
Here's an example error:
"Google Translate Error on checksum 48af8c32261d9cb8911d99168a6f5b21: https://www.googleapis.com/language/translate/v2?q=QUERYSTRING&source=ja&target=en&key=MYKEY&format=text&alt=json returned "User Rate Limit Exceeded">"
def _google_translate_callback(self, request_id, response, err):
if err:
print 'Google Translate Error on request_id %s: %s' % (request_id, err)
print 'Backing off for %d seconds.' % self.backoff
sleep(self.backoff)
if self.backoff < 4096:
self.backoff = self.backoff * 2
self._translate_array_google_helper()
else:
translation = response['translations'][0]['translatedText'] \
.replace('"', '"') \
.replace(''', "'")
self.translations.append((request_id, translation))
if is_done():
self.is_translating = False
else:
self.current_group += 1
self._translate_array_google_helper()
def _translate_array_google_helper(self):
if self.current_group >= len(self.groups):
self.is_translating = False
return
service = self.google_translator.translations()
group = self.groups[self.current_group]
batch = self.google_translator.new_batch_http_request(
callback=self._google_translate_callback
)
for text, request_id in group:
format_ = 'text'
if is_html(text):
format_ = 'html'
batch.add(
service.list(q=text, format=format_,
target=self.to_lang, source=self.from_lang),
request_id=request_id
)
batch.execute()

Resources