Input constantly received as 'str' - python-3.x

base = (.75)
hood = (.70)
pipeAura = (.9)
cloak = (.85)
glimmer = (.85)
null = (.78)
heap = (.88)
corrosive = (.75)
spiritBear = (.67)
spellShield = (.5)
berserkersBlood = (.5)
pipe = hood * pipeAura
antimage = spellShield * base
viper = corrosive * base
huksar = berserkersBlood * base
meepo = (.65) * base
veil = (1.25)
pudge = heap * base
input1 = input('What hero are you trying to kill?(antimage, viper, huskar, meepo, pudge)')
input2 = input('What item is the hero holding/using/affected by? (hood, pipeAura, cloak, glimmer, pipe, veil)')
input3 = input('is the hero affected by null field? (yes/no)')
userHealth = input("what is the hero's current hp?")
if input3 == null:
null = (.78)
else:
null = 1
magicResist = (1 - (input1) * (input2) * (null))
The context of many of these names and the idea may not make sense to many of you, but my problem is when i finish giving the input, it gives me the error" magicResist = (1 - (input1) * (input2) * (null))
TypeError: can't multiply sequence by non-int of type 'str'" I need help with this, and i am wondering why it considers them strings, even though all of the inputs trace back to floats with the defined variables

Input returns strings since python2. Before this raw_input returned a string and input returned the evaluated value.
If you want your input be evaluated you could combine input with eval.
inputN = eval(input("message..."))
But you should set the locals and globals passed to eval, to allow specific values or as security-reasons.

Input returns a string. If you want the user to enter a string (in your example that would be the name of the hero or the item) and want to use the appropriate value you calculated before, you might use a dictionary:
# [...]
antimage = spellShield * base
viper = corrosive * base
# [...]
heroes = {
'antimage': antimage,
'viper': viper,
# and so on
}
input1 = input('What hero are you trying to kill?(antimage, viper, huskar, meepo, pudge)')
hero = heroes.get(hero, 1) # I specify 1 as the default if the key is not present in the dictionary, you might specify a more suitable value
Do the same for the items and you can use the variables to calculate the result:
magicResist = (1 - hero * item * null)

Related

Find sequences of minimum 3 values that differ only by 0.5%

lets say I have a list like [1,2,1.5,2,1.99,2.01,4] and I want my function to find the sequence [2,1.99,2.01] and build a new list of it. This can happen multiple times while looping over the initial list. I hope my problem is understandable.
Thanks in advance
This is my attempt:
import itertools
Support = []
Liste1 = [1,2,1.5,2,1.99,2.01,4]
Liste2 = Liste1[1:]
Liste1.pop(-1)
for S1,S2 in itertools.zip_longest(Liste1, Liste2):
if S2<=1.05*S1 and S2>=0.95*S1:
Support.append(S1)
The problem is that this loop will compare the value to the value before and not to the first value which was detected as the start of a series.
Layer1 = [round(x,2) for x in list(data["Close"])]
Layer2 = Layer1[0:1]
Layer1.pop(0)
Layer3 = []
Layer4 = []
for element in Layer1:
if element < 1.01*Layer2[0] and element > 0.99*Layer2[0]:
Layer2.append(element)
if len(Layer2)>= 6:
Layer3.extend(Layer2)
Layer4.append(statistics.mean(Layer3))
Layer3.clear()
Layer2.clear()
Layer2.append(element)
else:
Layer2.clear()
Layer2.append(element)
R_S = sorted([round(s,2) for s in Layer4])
R_S_clean = R_S[0:1]
R_S.pop(0)
for element in R_S:
if element >= 1.01*R_S_clean[-1] or element <= 0.99*R_S_clean[-1]:
R_S_clean.append(element)
R_S_clean_rev = reversed(R_S_clean)
for element in R_S_clean_rev:
if element < Price:
Support = element
Delta_S = str(abs(round((100-((100/element)*Price)),2))) + "%"
break
else:
Support = "/"
Delta_S = "/"
for element in R_S_clean:
if element > Price:
Resistance = element
Delta_R = str(abs(round((100-((100/element)*Price)),2))) + "%"
break
else:
Resistance = "/"
Delta_R = "/"
This is my workaround, time will tell if the performance is good enough.

Appending max value of a zipped list

I have these three lists:
bankNames = ["bank1","bank2","bank3"]
interestRate = (0.05,0.01,0.08)
namePlusInterest = zip(interestRate,bankNames)
print(max(list(namePlusInterest)))
the print function returns an output of:
(0.08, 'bank3')
I want to be able to split the output into individual variables (for example):
MaxRate = 0.08
MaxBank = 'bank3'
So for later in my code I can say:
print(MaxBank + "has the highest interest rate of" + MaxRate)
You can use tuple unpacking to get each individual element from the tuple:
bankNames = ["bank1", "bank2", "bank3"]
interestRate = (0.05, 0.01, 0.08)
namePlusInterest = zip(interestRate, bankNames)
MaxRate, MaxBank = max(list(namePlusInterest))
print(f"{MaxBank} has the highest interest rate of {MaxRate}")

TypeError: 'int' object is not iterable when calculating mean

I am trying to read different values from a file and to store them in a list. After that, I need to take their mean and in doing so I am getting the error above. Code is working up to to line
"Avg_Humidity.append(words[8])"
Here it is:
def monthly_report(path,year,month):
pre_script="Murree_weather"
format='.txt'
file_name = pre_script + year + month+format
name_path=os.path.join(path,file_name)
file = open(name_path, 'r')
data = file.readlines()
Max_Temp = []
Min_Temp = []
Avg_Humidity = []
for line in data:
words = line.split(",")
Max_Temp.append(words[1])
Min_Temp.append(words[3])
Avg_Humidity.append(words[8])
Count_H, Count_Max_Temp, Count_Min_Temp, Mean_Max_Temp, Mean_Min_Temp,
Mean_Avg_Humidity=0
for iterate in range(1,len(Max_Temp)):
Mean_Max_Temp= Mean_Max_Temp+Max_Temp(iterate)
Count_Max_Temp=Count_Max_Temp+1
Mean_Max_Temp=Mean_Max_Temp/Count_Max_Temp
for iterate in range(1,len(Min_Temp)):
Mean_Min_Temp= Mean_Min_Temp+Min_Temp(iterate)
Count_Min_Temp=Count_Min_Temp+1
Mean_Min_Temp=Mean_Min_Temp/Count_Min_Temp
for iterate in range(1,len(Avg_Humidity)):
Mean_Avg_Humidity= Mean_Avg_Humidity+Avg_Humidity(iterate)
Count_H=Count_H+1
Mean_Avg_Humidity=Mean_Avg_Humidity/Count_H
print("Mean Average Humidity = ",Mean_Avg_Humidity)
print("Mean Maximum Temperature = ",Mean_Max_Temp)
print("Mean Minimum Temperature = ",Mean_Min_Temp)
return
This line is incorrect:
Count_H, Count_Max_Temp, Count_Min_Temp, Mean_Max_Temp, Mean_Min_Temp, Mean_Avg_Humidity = 0
To fix, change it to:
Count_H = Count_Max_Temp = Count_Min_Temp = Mean_Max_Temp = Mean_Min_Temp = Mean_Avg_Humidity = 0
An alternative fix would be to leave the commas as they are and change the right-hand side to a list or tuple of zeroes that has the same number of elements as the left-hand side. But that would be less clear, and harder to maintain.

Expanding anonymous function into a string

I have a set of anonymous functions, and I want to convert them into strings. Normally I would just use func2str, but the problem is I want the variables and internal functions to be expanded out into their "true" values. The problem I'm running into is that MATLAB is keeping these by the names, but recognizing the values. Example
classdef Bclass
properties
equation
end
function obj = Bclass(inEquation, inValue)
obj.equation = #(t,y) inEquation(t,y) * inValue;
end
function out = getStr(obj)
out = func2str(obj.equation);
end
end
The problem is that the func2str call is outputting #(t,y) inEquation(t,y) * inValue, when I actually want it to output something like #(t,y) t*y * 5, if we had said b = Bclass(#(t,y) t*y, 5).
Is there a way to retrieve these variable values from MATLAB?
You can do this, but it could quickly become very difficult if your problem becomes any more complex than the example given above (i.e. more complicated anonymous functions, multiple nesting levels, etc.). You'll have to make use of the functions function to get information on the function handle, and its behavior may change between releases. Additionally, you'll have to do quite a bit of string manipulation (using functions like regexp, regexprep, strsplit, and strrep, as I do below).
I've tried to include here the most general approach I could, allowing for the following possibilities:
inEquation can be a non-anonymous function handle (i.e. #times).
inEquation can simply be passed along as is without actually being invoked.
inEquation can be called multiple times in the anonymous function.
The input arguments to inEquation can be named differently than what it is invoked with in obj.equation.
obj.equation can contain indexing operations.
First, we'll initialize some variables to mimic your example:
f1 = #(m, n) m*n; % Note the different variable names, but it will still work
inEquation = f1;
inValue = 5;
f2 = #(t, y) inEquation(t, y)*inValue; % Function constructed using workspace variables
Next, we'll get the function information for f2:
s = functions(f2);
varNames = fieldnames(s.workspace{1});
varValues = struct2cell(s.workspace{1});
out = s.function;
The workspace field holds the variable names and values that were used to construct f2, and the function field is the string you'd get by calling func2str on f2. We'll also need to compute a few things so we can correctly parse opening and closing parentheses in f2:
openIndex = (out == '(');
closeIndex = (out == ')');
parenIndex = cumsum(openIndex-[false closeIndex(1:end-1)]).*(openIndex | closeIndex);
Now, we'll loop over the workspace variables, convert their values to strings (if possible), and replace them in out:
for iVar = 1:numel(varNames)
name = varNames{iVar};
value = varValues{iVar};
if isa(value, 'function_handle') % Workspace variable is a function handle
value = func2str(value);
callIndex = strfind(out, [name, '('])+numel(name);
fcnParts = regexp(value, '#\({1}([^\)])*\){1}(\S)*', 'once', 'tokens');
if isempty(callIndex) % Function handle is not invoked
if isempty(fcnParts) % Non-anonymous function handle (i.e. #times)
value = ['#' value];
end
out = strrep(out, name, value);
elseif isempty(fcnParts) % Invoked function handle (i.e. #times)
out = strrep(out, name, value);
else % Invoked anonymous function handle
for iCall = callIndex
args = out(iCall+(1:find(parenIndex(iCall+1:end) == parenIndex(iCall), 1)-1));
value = regexprep(fcnParts{2}, ...
strcat('(?<!\w)', strsplit(fcnParts{1}, ','), '(?!\w)'), ...
strsplit(args, ','));
out = strrep(out, [name, '(', args, ')'], value);
end
end
elseif isnumeric(value) && isscalar(value) % Workspace variable is a numeric scalar
out = strrep(out, name, num2str(value));
end
end
And we get the desired result for out:
>> out
out =
#(t,y)t*y*5
Note that this will also work as expected with a non-anonymous function handle as well:
>> f1 = #times;
>> inEquation = f1;
>> inValue = 5;
>> f2 = #(t, y) inEquation(t, y)*inValue;
% Repeat above processing...
>> out
out =
#(t,y)times(t,y)*5
It will also work on some more complicated functions:
>> postVolt = #(g, V) -.05*g*(V+80);
>> preIdx = 5;
>> postIdx = 1;
>> index = 6;
>> obj.values = {};
>> f2 = #(t) postVolt(obj.values{preIdx}(index), obj.values{preIdx}(obj.voltIdx{postIdx}));
% Repeat above processing...
>> out
out =
#(t)-.05*obj.values{5}(6)*(obj.values{5}(obj.voltIdx{1})+80)

invalid literal int base 10 occurring sporadically with the same variable

I have a Python3.4.2/tkinter program that requests a numeric user-entry which I have as a StringVar: my issue is that sometimes( probably about 30% of the time) it returns the invalid literal int base 10 and sometimes it functions perfectly. When the base 10 issue occurs I have to close the app and reopen. Printing the StringVar always returns PY_VAR0 and from within the functions that use the StringVar, when the app functions, the number that was entered returns. When the base 10 issue occurs, the app 'crashes' returning only the PY_VAR0 and then the error message. If it were consistent I would understand where to hunt my error but with it behaving apparently irrationally I don't know how to start.
How do I go about investigating this issue?
The assignment part this:
to_choose = StringVar()
#print(to_choose)
text = "\n{0}\n {1}".format("Enter number", "of Draws", pady = 10)
instruction = Label(actions_label_frame, text =text, bg = 'dark sea green', fg = 'dark slate gray')
instruction.grid(column = 2, row= 2, sticky = N)
how_many_draws_entry = Entry(actions_label_frame, text = "", bd = 2, width = 3, bg = 'mint cream', fg = 'sea green', textvariable = to_choose, cursor = 'arrow', highlightcolor ='red')
The section that attempts to use the variable:
mains_results = []
draw = 0 # identifier for draw number to separate results clearly
main_num_draws = int(to_choose.get())
print("from main", main_num_draws)
# check for empty string
'''
try:
main_num_draws = int(to_choose.get())
except ValueError:
main_num_draws = 1
'''
while draw < main_num_draws: # loop 1
merged = list(itertools.chain.from_iterable(final_list)) # flatten list
# print(len(merged)) #check length of list for pseudocheck
random.shuffle(merged)
chosen = [] # accumulate eack pick in this list: reset here as well
draw += 1 # increment draw identifier
while len(chosen) <= 5: # loop 2, to choose the five numbers of a draw
pick = random.choice(merged)
chosen.append(pick)
merged = list(filter((pick).__ne__, merged)) # remove draw from choices(numbers)
#print(len(merged)) #pseudocheck that values have been removed
chosen.sort()
mains_results.append(chosen)
and the error message:
main_num_draws = int(to_choose.get())
ValueError: invalid literal for int() with base 10: ''
The error message is telling you exactly what's wrong. When you do this:
main_num_draws = int(to_choose.get())
... the error message is telling you that to_choose.get() is returning an empty string. An empty string is an invalid integer.
You need to either guarantee that the variable always has a valid integer in it, or you need to catch that error and handle it appropriately. Oddly, you have commented out code that does exactly that.
If you print one of these variables and see something like PY_VAR0, that just means you are doing something like print the_variable rather than print the_variable.get(). The string representation of the object isn't the value, it's a unique internal name (dumb design decision on the part of Tkinter designers IMO, but it is what it is).

Resources