def Divider(d, ratio): d["divider"] = set() # First check using equal resistors for R in d["R"]: Div(d, float(ratio), R, R) for R1, R2 in combinations(d["R"], 2): Div(d, float(ratio), R1, R2) # Print report div = list(d["divider"]) if not div: out("No divider can be made") return div.sort() out("Voltage divider with ratio = ", ratio, ", tolerance = ", sig(d["-t"]*100, 2), "%", sep="") out() out("% dev from") out("desired ratio R1 R2 Total Res.") out("------------- ---------- ---------- ----------") for rat, r1, r2 in div: dev = 100*((rat - float(ratio))/float(ratio)) pct = sig(dev) if dev >= 0: pct = " " + pct R1, R2, R = fp.engsi(r1), fp.engsi(r2), fp.engsi(r1 + r2) if not dev: fg(highlight) out(" {0:10} {1:^10} {2:^10} {3:^10}".format(pct, R1, R2, R)) normal()
def Quotient(d, ratio): # Ignore a requested ratio of 1, as any pair of resistors will work if ratio == 1: out("Quotient cannot be 1") exit(1) d["resistances"], t, Ratio = set(), d["-t"], float(ratio) for R1, R2 in combinations(d["R"], 2): q1 = R1/R2 q2 = 1/q1 if (1 - t)*Ratio <= q1 <= (1 + t)*Ratio: d["resistances"].add((q1, R1, R2)) elif (1 - t)*Ratio <= q2 <= (1 + t)*Ratio: d["resistances"].add((q2, R2, R1)) # Print report res = list(d["resistances"]) if not res: out("No resistor combinations that meet tolerance") return res.sort() out("Desired ratio = ", ratio, ", tolerance = ", sig(d["-t"]*100, 2), "%", sep="") out() out("% dev from") out("desired ratio R1 R2") out("------------- ---------- ----------") for val, r1, r2 in res: dev = 100*((val - Ratio)/Ratio) pct = sig(dev, 2) if dev >= 0: pct = " " + pct R1, R2 = fp.engsi(r1), fp.engsi(r2) if not dev: fg(highlight) out(" {0:10} {1:^10} {2:^10}".format(pct, R1, R2)) normal()
def Report(): S = { "Files" : [], "ProcessDistribution" : normal, "ProcessMu" : 10, "ProcessSigma" : 1, "MeasurementDistribution" : normal, "MeasurementMu" : 0, "MeasurementSigma" : 1, "NumberOfLots" : 2, "PartsPerLot" : 10, "Specification" : (9.5, 10.5), } seed(8353475) # Make the random number stream repeatable results = Manufacture(S) p = sig((S["ProcessMu"], S["ProcessSigma"])) m = sig((S["MeasurementMu"], S["MeasurementSigma"])) s = sig(S["Specification"]) nl = str(S["NumberOfLots"]) ppl = str(S["PartsPerLot"]) out(''' Small manufacturing example: Process (mu, sigma) = {p} Measureement (mu, sigma) = {m} Spec = {s} Number of lots = {nl} Parts per lot = {ppl} '''[1:].format(**locals())) out("Good parts made =\n", sig(results["parts"][0])) out("Bad parts made =\n", sig(results["parts"][1])) out("Good parts tested good =\n", sig(results["parts"][2])) out("Good parts tested bad =\n", sig(results["parts"][3])) out("Bad parts tested good =\n", sig(results["parts"][4])) out("Bad parts tested bad =\n", sig(results["parts"][5]))
def Pairs(args, d): if len(args) != 4: Usage(d) parallel = True if args[3] == "p" else False target_value = float(args[2]) if target_value <= 0: Error("Target value must be > 0") # Read file data lines = [i.strip() for i in open(args[1]).readlines()] # Check that we have only one blank line and an equal number of # resistance values on either side of it. r1, r2, first = [], [], True for line in lines: if not line: first = False continue if first: r1.append(float(line)) else: r2.append(float(line)) if not r1 or not r2: Error("Missing blank line in resistor file '%s'" % args[1]) if len(r1) != len(r2): Error("Two resistor sets don't have equal number in resistor file '%s'" % args[1]) # Calculate the set of resultant resistances results = [] for i in r1: for j in r2: if parallel: r = 1/(1/i + 1/j) else: r = i + j pct_dev = 100*(r - target_value)/target_value pct_dev = 0 if abs(pct_dev) < 1e-10 else pct_dev results.append([pct_dev, r, i, j]) results.sort() model, file = "parallel" if parallel else "series", args[1] out(''' Model = {model} File = {file} % dev from mean value Resistance R1 R2 ---------- ---------- ------------- ------------- '''[1:-1].format(**locals())) sig.digits = d["-d"] for i in results: r, r1, r2 = i[1:] out("%9s%% " % sig(i[0], 2), nl=False) out("%-10s " % sig(r), nl=False) out("%-10s " % sig(r1), nl=False) out("%-10s" % sig(r2))
def Resistance(d, resistance): d["resistances"] = set() # First see if we have an exact match if resistance in d["R"]: d["resistances"].add((resistance, "e", resistance, 0)) else: # First check using equal resistors for R in d["R"]: Res(d, resistance, R, R) for R1, R2 in combinations(d["R"], 2): Res(d, resistance, R1, R2) res = list(d["resistances"]) if not res: out("No resistor combinations that meet tolerance") return # Check if we have too many entries; if so, whittle down the list to # the closest N. clipped = False if len(res) > d["-n"]: # Sort by absolute value of tolerance tol = lambda tgt, val: abs(val - tgt)/val r = [(tol(resistance, i[0]), i) for i in res] # Decorate with abs val r.sort() res = [i[1] for i in r[:d["-n"]]] clipped = True # Print report res.sort() out("Desired resistance = ", d["desired"], " = ", sig(d["res"]) + ", tolerance = ", sig(d["-t"]*100, 2), "%", sep="") if clipped: out("Closest %d matches shown" % d["-n"]) out() out("% dev from") out("desired res. R1 R2 Connection") out("------------- ---------- ---------- ----------") for val, c, r1, r2 in res: dev = 100*((val - resistance)/resistance) pct = sig(dev, 2) if dev >= 0: pct = " " + pct R1, R2 = fp.engsi(r1), fp.engsi(r2) conn = {"s":"series", "p":"parallel", "e":"exact"}[c] if (d["-p"] and c == "s") or (d["-s"] and c == "p"): continue if not dev: fg(highlight) if c == "e": out(" {0:10} {1:^10} {2}".format(pct, R1, conn)) else: out(" {0:10} {1:^10} {2:^10} {3}".format(pct, R1, R2, conn)) normal()
def FloatingPoint(n, m, inc, d): fmt = "%%.%dg" % d["-d"] for i in frange(n, m, inc, include_end=d["-e"]): if i <= float(m): if d["-s"]: out(sig(i), "", nl=d["-n"]) else: out(fmt % i, "", nl=d["-n"]) if not d["-n"]: out()
def yt_download(video_id): """Request download link from youtube-mp3.com.""" timestamp = str(int(time.time())) tail = random.sample(range(100, 999), 2) # Generate timestamp that complies with site's version ts = [timestamp + str(min(tail)), timestamp + str(max(tail))] push = 'http://www.youtube-mp3.org/a/pushItem/?item=https%3A//www.youtube.com/watch%\3Fv%3D{}&el=ma&bf=false&r={}&s={}'.format( video_id, ts[0], sig(ts[0])) info = 'http://www.youtube-mp3.org/a/itemInfo/?video_id={}&ac=www&t=grp&r={}&s={}'.format( video_id, ts[1], sig(ts[1])) requests.get(push) # Make sure video is converted r = requests.get(info) txt = r.text.split('info = ')[1][:-1] # JSON-friendly part of response js = json.loads(txt) dl_link = ( 'http://www.youtube-mp3.org/get?video_id={}&ts_create={}&r=MTg4LjIzMS4xMzEuNzQ%3D&h2={}&s={}' .format(video_id, js["ts_create"], js["h2"], sig(js["h2"]))) return dl_link
def DividerRatios(d, res): r = [Interpret(i) for i in res] R = sum(r) out("String of voltage dividers:") out(" Resistors given:") for i in res: out(" ", i) out(" Total resistance =", fp.engsi(R)) out(" Divider ratios:") for i in range(1, len(r)): D = sum(r[i:])/R out(" %2d " % i, sig(D, 4))
def List(d): out("On-hand resistors:\n") out(on_hand[1:-1]) out("-"*70) out("EIA resistance series:") for n in (6, 12, 24, 48, 96): out("E%d:" % n) digits = 2 if n < 48 else 3 s = [] for num in EIA[n]: s.append(sig(num, digits)) for i in Columnize(s): out(" ", i)
def Series(d, res): '''Find a set of resistors that sum to the desired value but remain less than or equal to it. ''' resistors = d["R"] resistors.sort() resistors = list(reversed(resistors)) used = [] while resistors and sum(used) <= res: if resistors[0] + sum(used) <= res: used.append(resistors[0]) else: del resistors[0] out("Sum =", fp.engsi(sum(used))) out(" Resistor % of total") r = 0 for i in used: r += i out(" %-10s" % fp.engsi(i), " ", sig(100*r/res, 6))
def Report(d): angle = sig(d["angle"]) arc = sig(d["arc"]) chord = sig(d["chord"]) diameter = sig(d["diameter"]) height = sig(d["height"]) radius = sig(d["radius"]) print('''Results: Angle {angle} deg Arc {arc} Chord {chord} Diameter {diameter} Height {height} Radius {radius}'''.format(**locals()))
def Calculate(__vars, __d): # Get vars into our local namespace if __vars is not None: for __k in __vars: if len(__k) > 2 and __k[:2] == "__": continue exec("%s = __vars['%s']" % (__k, __k)) try: if radius and angle: if dbg: print("radius, angle", sig(radius), sig(angle)) z = radius*COSD(0.5*angle) height = radius - z chord = 2.*radius*SIND(0.5*angle) arc = radius*angle*RPD elif radius and chord: if dbg: print("radius, chord", sig(radius), sig(chord)) angle = 2.*ASND(0.5*chord/radius) z = radius*COSD(0.5*angle) height = radius - z arc = radius*angle*RPD elif radius and height: if dbg: print("radius, height", sig(radius), sig(height)) z = radius - height angle = 2.*ACSD(z/radius) chord = 2.*radius*SIND(0.5*angle) arc = radius*angle*RPD elif radius and arc: if dbg: print("radius, arc", sig(radius), sig(arc)) angle = DPR*arc/radius z = radius*COSD(0.5*angle) height = radius - z chord = 2.*radius*SIND(0.5*angle) elif angle and chord: if dbg: print("angle, chord", sig(angle), sig(chord)) radius = 0.5*chord/SIND(0.5*angle) z = radius*COSD(0.5*angle) height = radius - z arc = radius*angle*RPD elif angle and height: if dbg: print("angle, height", sig(angle), sig(height)) radius = height/(1. - COSD(0.5*angle)) z = radius - height chord = 2.*radius*SIND(0.5*angle) arc = radius*angle*RPD elif angle and arc: if dbg: print("angle, arc", sig(angle), sig(arc)) radius = DPR*arc/angle z = radius*COSD(0.5*angle) height = radius - z chord = 2.*radius*SIND(0.5*angle) elif chord and height: if dbg: print("chord, height", sig(chord), sig(height)) radius = (4.*height*height + chord*chord)/(8.*height) z = radius - height angle = 2.*ACSD(z/radius) arc = radius*angle*RPD elif chord and arc: if dbg: print("chord, arc", sig(chord), sig(arc)) h, t1, t2, dt, hbest, k = 0, 1, 180, 1, 1e6, 0 while ABS(h - chord) > 1e-6 and k < 6: angle = t1 while angle <= t2: radius = DPR*arc/angle h = 2.*radius*SIND(0.5*angle) if ABS(h - chord) < hbest: hbest = ABS(h - chord) tbest = angle angle += dt t1 = tbest - dt t2 = tbest + dt dt *= 0.1 k += 1 # Note that angle will not have an uncertainty associated # with it because it was derived through iteration in the # loop. angle = tbest radius = DPR*arc/angle height = radius*(1 - COSD(0.5*angle)) elif height and arc: if dbg: print("height, arc", sig(height), sig(arc)) h, t1, t2, dt, hbest, k = 0, 1, 180, 1, 1e6, 0 while ABS(h - height) > 1e-6 and k < 6: angle = t1 while angle <= t2: radius = DPR*arc/angle h = radius*(1 - COSD(0.5*angle)) if ABS(h - height) < hbest: hbest = ABS(h - height) tbest = angle angle += dt t1 = tbest - dt t2 = tbest + dt dt *= 0.1 k += 1 # Note that angle will not have an uncertainty associated # with it because it was derived through iteration in the # loop. angle = tbest radius = DPR*arc/angle chord = 2.*radius*SIND(0.5*angle) except Exception as e: if dbg: print("Exception in Calculate(): ", str(e)) return False # Put answers into dictionary __d["diameter"] = 2*radius __d["radius"] = radius __d["angle"] = angle __d["chord"] = chord __d["height"] = height __d["arc"] = arc return True
X = Z * sin(theta) print(" Rs = ", E(Rs), "ohm = ESR", sep="") print(" Rp = ", E(Rp), "ohm", sep="") print(" X = ", E(X), "ohm", sep="") if isinf(Cs): print(" Cs = inf") else: print(" Cs = ", E(Cs), "F", sep="") print(" Cp = ", E(Cp), "F", sep="") print(" Ls = ", E(Ls), "H", sep="") if isinf(Lp): print(" Lp = inf") else: print(" Lp = ", E(Lp), "H", sep="") if isinstance(Q, float): print(" Q =", sig(Q)) print(" D =", sig(D)) else: print(" Q =", Q) print(" D =", D) else: # Use f-strings o = "Ω" Rs = f"{E(Rs)}{o}" Rp = f"{E(Rp)}{o}" X = E(Z * sin(theta)) + o if isinf(Cs): Cs = f"∞ F" else: Cs = f"{E(Cs)}F" Cp = f"{E(Cp)}F"
def Report(d): S, w = d["solution"], 15 angle_measure = 1/d["angle_measure"] if angle_measure == 1: dm = "rad" else: dm = "deg" ds = " "*5 S1, S2, S3, A1, A2, A3 = [S[i] for i in "S1 S2 S3 A1 A2 A3".split()] s1, s2, s3 = [sig(i) for i in (S1, S2, S3)] a1, a2, a3 = [sig(i*angle_measure) for i in (A1, A2, A3)] GetOtherFacts(S1, S2, S3, A1, A2, A3, d) area = sig(d["area"]) r = sig(d["r_inscribed"]) R = sig(d["R_circumscribed"]) di = sig(d["r_inscribed"]*2) D = sig(d["R_circumscribed"]*2) p = sig(d["perimeter"]) title = "Triangle solution" fmt = '''{title}: Sides {ds} {s1:{w}} {s2:{w}} {s3:{w}} Angles ({dm}) {a1:{w}} {a2:{w}} {a3:{w}} Area {area} Perimeter {p} Inscribed circle radius = {r}, diameter = {di} [Note 1] Circumscribed circle radius = {R}, diameter = {D} [Note 2]''' out(fmt.format(**locals())) # Check for 2nd solution if "S1_2" in S: S1, S2, S3, A1, A2, A3 = [S[i] for i in "S1_2 S2_2 S3_2 A1_2 A2_2 A3_2".split()] GetOtherFacts(S1, S2, S3, A1, A2, A3, d) s1, s2, s3 = [sig(i) for i in (S1, S2, S3)] a1, a2, a3 = [sig(i*angle_measure) for i in (A1, A2, A3)] title = "Second solution" area = sig(d["area"]) r = sig(d["r_inscribed"]) R = sig(d["R_circumscribed"]) di = sig(d["r_inscribed"]*2) D = sig(d["R_circumscribed"]*2) p = sig(d["perimeter"]) out(fmt.format(**locals())) out(''' [1] Center located by angle bisectors. [2] Center located by perpendicular bisectors of the sides.''')
if __name__ == "__main__": d = {} # Options dictionary args = ParseCommandLine(d) price = None CorrectArgs(args) if len(args) == 2: year1, year2 = [int(i) for i in args] elif len(args) == 3: price = float(args[0]) p = args[0] # User's string for price year1, year2 = [int(i) for i in args[1:]] else: raise Exception("Logic bug") c = d["cpi"] if year1 not in c: print("Year", year1, "not in data") exit(1) if year2 not in c: print("Year", year2, "not in data") exit(1) ratio = c[year2] / c[year1] if price is not None: print("${} in {} = ${} in {}".format(p, year1, sig(price * ratio), year2)) print("${} in {} = ${} in {}".format(p, year2, sig(price / ratio), year1)) else: print("$1 in {} = ${} in {}".format(year1, sig(ratio), year2)) print("$1 in {} = ${} in {}".format(year2, sig(1 / ratio), year1))
def do_sig(self, line): _sig = sig(self.line_bot_api, self.event) return _sig.calculate(line)
def PrintReport(d): S, R, w = d["settings"], d["results"]["parts"], 79 if S["Title"].strip(): for line in S["Title"].split("\n"): out("{0:^{1}s}".format(line, w)) tm = time.asctime(time.localtime(time.time())) out("{0:^{1}s}".format(tm, w)) if d["seed"] is not None: s = "Seed = " + d["seed"] out("{0:^{1}s}".format(s, w)) out() s = "Source files and their hashes" out(s) out("-"*len(s)) d["settings"]["Files"].sort() for file in d["settings"]["Files"]: out(" ", Hash(open(file).read())[0], file) out() # Process details sig.digits = sd = S["SignificantDigits"] proc_mean, proc_s = sig(S["ProcessMu"]), sig(S["ProcessSigma"]) meas_mean, meas_s = sig(S["MeasurementMu"]), sig(S["MeasurementSigma"]) pdist, mdist = S["ProcessDistributionName"], S["MeasurementDistributionName"] N = S["NumberOfLots"]*S["PartsPerLot"] nparts = FmtI(N) nl, ppl = FmtI(S["NumberOfLots"]), FmtI(S["PartsPerLot"]) spec = sig(list(S["Specification"])) na, nw, nd, sp = ">", 15, 30, " "*10 out(''' Process characteristics ({sd} significant figures) ----------------------- Distributions Process = {pdist} Measurement = {mdist} Process mean {sp}{proc_mean:{na}{nw}} Process standard deviation {sp}{proc_s:{na}{nw}} Measurement bias {sp}{meas_mean:{na}{nw}} Measurement standard deviation {sp}{meas_s:{na}{nw}} Part acceptance interval {sp}{spec:{na}{nw}} Number of lots made {sp}{nl:{na}{nw}} Parts per lot {sp}{ppl:{na}{nw}} '''[1:].format(**locals())) # What was actually produced good, bad = len(R[0]), len(R[1]) goodi, badi = FmtI(good), FmtI(bad) goodp, badp = sig(100*good/float(N)), sig(100*bad/float(N)) out(''' True (unknowable) process output -------------------------------- Total parts made {nparts:{na}{nw}} Actual good {goodi:{na}{nw}} ({goodp}% of total) Actual bad {badi:{na}{nw}} ({badp}% of total) '''[1:].format(**locals())) # What the measurements said was produced gtg, gtb = len(R[2]), len(R[3]) btg, btb = len(R[4]), len(R[5]) gtgi, gtbi = FmtI(gtg), FmtI(gtb) btgi, btbi = FmtI(btg), FmtI(btb) gtgp = sig(100*gtg/float(N)) gtbp = sig(100*gtb/float(N)) btgp = sig(100*btg/float(N)) btbp = sig(100*btb/float(N)) all = np.concatenate((R[2], R[3], R[4], R[5])) mean = sig(np.average(all)) sdev = sig(np.sqrt(np.cov(all))) low, high = sig(np.min(all)), sig(np.max(all)) out(''' What 100% inspection determined ------------------------------- Good tested good {gtgi:{na}{nw}} {gtgp:{na}}% Good tested bad {gtbi:{na}{nw}} {gtbp:{na}}% <-- Producer's risk Bad tested good {btgi:{na}{nw}} {btgp:{na}}% <-- Consumer's risk Bad tested bad {btbi:{na}{nw}} {btbp:{na}}% Process mean {mean:{na}{nw}} Process std dev {sdev:{na}{nw}} Min, max measured [{low}, {high}] '''[1:].format(**locals())) # Production results ship = FmtI(gtg + btg) scrap = FmtI(gtb + btb) try: ship_badp = sig(100*gtb/float(gtg + gtb)) except ZeroDivisionError: ship_badp = sig(0) try: scrap_goodp = sig(100*btg/float(btg + btb)) except ZeroDivisionError: scrap_goodp = sig(0) yieldr = "actual = " + sig(100*good/float(N)) + "%," yieldm = "measured = " + sig(100*(gtg + btg)/float(N)) + "%" scrapr = "actual = " + sig(100*bad/float(N)) + "%," scrapm = "measured = " + sig(100*(gtb + btb)/float(N)) + "%" ya, ysw = ">", 15 out(''' Production results ------------------ Parts shipped {ship:{na}{nw}} {ship_badp}% of these are bad parts Parts scrapped {scrap:{na}{nw}} {scrap_goodp}% of these are good parts Yield {yieldr:{ya}{ysw}} {yieldm} Scrapped {scrapr:{ya}{ysw}} {scrapm} '''[1:].format(**locals())) # Financial results # Per part: nship, nscrap, n = gtg + btg, gtb + btb, float(N) cprodpp = S["CostToProducePart"] ctestpp = S["CostToTestPart"] cshippp = S["CostToShipPart"] cscrappp = S["CostToScrapPart"] cvohpp = S["CostVariableOverhead"] cfohpp = S["CostFixedOverhead"]/float(N) ccustbadpp = S["CustomerCostPerBadPart"] # Formatted as integers cprod = FmtI(int(cprodpp*n)) ctest = FmtI(int(ctestpp*n)) cship = FmtI(int(ctestpp*float(nship))) cscrap = FmtI(int(cscrappp*float(nscrap))) cvoh = FmtI(int(cvohpp*n)) cfoh = FmtI(int(float(S["CostFixedOverhead"]))) ctprod = (n*(cprodpp + ctestpp + cvohpp + cfohpp) + ctestpp*float(nship) + cscrappp*float(nscrap)) ctprodi = FmtI(int(ctprod)) ctprodpp = (ctprod/n) ppstart = ctprod/n try: ppship = ctprod/float(nship) except ZeroDivisionError: ppship = 0 # Percentages of total production cost ppc = 100*cprodpp*n/ctprod ptc = 100*ctestpp*n/ctprod psc = 100*ctestpp*float(nship)/ctprod pcs = 100*cscrappp*float(nscrap)/ctprod pvo = 100*cvohpp*n/ctprod pfo = 100*float(S["CostFixedOverhead"])/ctprod tpc = 100 # Revenue & customer sppp = S["SellingPricePerPart"] trev = sppp*float(gtg + btg) trevi = FmtI(int(trev)) gp = FmtI(int(trev - ctprod)) try: gpp = 100*(trev - ctprod)/trev except Exception: gpp = "--" custloss = ccustbadpp*float(btg) custlossi = FmtI(int(custloss)) try: custlosspp = custloss/float(nship) except ZeroDivisionError: custlosspp = 0 mo = ">15s" kd, pp, pt = ">10.1f", ">8.3f", ">5.1f" pps = "per part started" ppsh = "per part shipped" prp = "per received part" out(''' Money Amount % Cost per part ----- --------- ----- ------------- Production cost {cprod:{mo}} {ppc:{pt}} {cprodpp:{pp}} Testing cost {ctest:{mo}} {ptc:{pt}} {ctestpp:{pp}} Shipment cost {cship:{mo}} {psc:{pt}} {cshippp:{pp}} Cost to scrap {cscrap:{mo}} {pcs:{pt}} {cscrappp:{pp}} Variable overhead cost {cvoh:{mo}} {pvo:{pt}} {cvohpp:{pp}} Fixed overhead cost {cfoh:{mo}} {pfo:{pt}} {cfohpp:{pp}} --------- ----- -------- Total production cost {ctprodi:{mo}} {tpc:{pt}} {ppstart:{pp}} {pps} {ppship:{pp}} {ppsh} Revenue {trevi:{mo}} {sppp:{pp}} selling price Gross profit {gp:{mo}} '''[1:-1].format(**locals())) if gpp == "--": out(''' % gross profit --% Customer's loss {custlossi:{mo}} {custlosspp:{pp}} {prp} '''[1:-1].format(**locals())) else: out(''' % gross profit {gpp:{kd}}% Customer's loss {custlossi:{mo}} {custlosspp:{pp}} {prp} '''[1:-1].format(**locals()))