मेरे पास एक स्लाइडर है जिसका उपयोग मैं एक पैरामीटर (y) को बदलने के लिए करता हूं जिसमें मूल्यों की एक विस्तृत श्रृंखला हो सकती है। स्लाइडर की स्थिति एक पूर्णांक (x) के रूप में दी गई है।

मेरा पैरामीटर स्रोत की ऊर्जा रखता है, और इसमें 0.1 एनजे से 10 जे तक के मान हो सकते हैं। आवेदन उद्देश्यों के लिए मैं पैरामीटर चरण आकार होना चाहता हूं:

  • [०.१ एनजे - १.० µ जे] में ०.१ एनजे
  • ०.१ µJ में [१.० µJ-१.० mJ]
  • [1.0 एमजे - 1.0 जे] में 0.1 एमजे
  • ०.१ जे [१.० जे - १०.० जे] में

मैं पूर्णांक विभाजन (//) और शेष (%) संचालन का उपयोग करके इन मानों (x => y) को परिवर्तित करने का प्रयास कर रहा हूं, लेकिन जब मैं क्रॉस ओवर प्राप्त करता हूं तो मैं समस्याओं में भाग लेता हूं उदाहरण के लिए, एक उप श्रेणी से दूसरी तक।

X = 9999 y = 999.9 nJ देता है, जो इसे होना चाहिए, लेकिन फिर x = 10000 y = 0.0 µJ देता है, जो तब सिस्टम में 0 है और 999.9 nJ से बहुत कम है। अगला चरण (x = १०००१) y = ०.१ µJ देता है जो कि ९९९.९ nJ से भी कम है।

आदर्श रूप से y के चरण ९९९.९ nJ-१.० µJ-१.१ µJ होने चाहिए।

यह MWE ENTER दबाए बिना कुंजियों के इनपुट को पढ़ने के लिए की डिटेक्शन का उपयोग करता है।

import math as m
import sys, termios, tty, os, time

prefixes =   {-18:'a', -15:'f', -12:'p', -9:'n',    # Prefixes for displaying the value
        -6:'\u03bc', -3:'m', #-2:'c', -1:'d',
        +0:'', #+1:'da', +2:'h', 
        +3:'k', +6:'M', +9:'G', +12:'T', +15:'P', +18:'E'}

def getch():                    # Get character from keyboard without waiting for enter
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

def calcy():                        # Convert from x integer to y value for display
    print("x: " + repr(x))
    exp2 = 3*((x/resolution) // 1e+3) + exp0    # integer division
    yp2 = round((x/resolution)%(1e+3), digits)  # remainder
    y2 = round(yp2 * m.pow(10, exp2), int(digits-exp2))
    print("y: " + repr(y2) + "   equal to " + repr(yp2) + str(prefixes[exp2]) + "J\n")

button_delay = 0.1

y = float(input("Give starting value:"))    # Choose a value to start from

exp0 = -9                                     # Exponent of minimum range [nJ]
digits = 1                                  # Number of decimals to be used
resolution = m.pow(10, 1)                   # The number of points for a change of size 1

exp = 0                                     # Exponent of y
yp = y                                      # Short number of y
while yp < 1/resolution:                    # While the number is not in the prefixed unit
    yp = yp*1e+03                           # Multiply yp by 1000 (10³)
    exp -= 3                                # Exponent increases by 3

yp = round(y * m.pow(10, -exp), digits)     # The display value 
x = int((yp + (exp - exp0)/3 * 1e+3) * resolution)   # Integer value representing the silder value

calcy()                                     # Calculate y from x integer

while True:
    char = getch()            # Get pressed key

    if char == 'q':           # If it was q, quit
        exit(0)
    elif char == '+':         # If it was +, increase x by one and
        x += 1                # recalculate y
        calcy()
        time.sleep(button_delay)
    elif char == '-':        # If it was -, decrease x by one and 
        x -= 1               # recalculate y
        calcy()
        time.sleep(button_delay)
    else:
        print(char)
        time.sleep(button_delay)

अगर आप इस प्रोग्राम को आजमाना चाहते हैं, तो मैं आपको 500e-9 को शुरुआती मान के रूप में देने और - को y = 999.9 nJ तक पहुंचाने के लिए 6 बार पुश करने की सलाह देता हूं, क्योंकि यहीं चीजें गलत हो जाती हैं।

मैं समझता हूं कि मेरे द्वारा उपयोग किए जा रहे एल्गोरिथम के साथ x = 10001 के लिए 0.1 µJ में परिवर्तित होना तर्कसंगत है, लेकिन मुझे नहीं पता कि इसे कैसे हल किया जाए। यदि आप केवल + और - बटन के साथ मान को बदल सकते हैं, तो कोई सीधे 9999 से 10011 तक जा सकता है, जो तार्किक रूप से y = 1.1 µJ देगा, लेकिन फिर मैं इस तथ्य को कैसे संभालूंगा कि वास्तविक स्लाइडर को माउस से घसीटा जा सकता है?

कृपया मुझे इस बारे में कोई विचार दें कि इसे कैसे हल किया जाए।

0
Kajsa 29 अक्टूबर 2018, 03:34

2 जवाब

सबसे बढ़िया उत्तर

टिप्पणियों और @ डेविस-हेरिंग के सुझाव के लिए धन्यवाद, मुझे लगता है कि मैंने इसे हल कर लिया है। फ़ंक्शन को अब विभिन्न रिज़ॉल्यूशन (चरण आकार) और शुरुआती घातांक (exp0) के लिए समायोजित किया जा सकता है।

def calcy(x):
    if x < (1000*resolution - 1):        # The number of values from the start to the first prefix change
        exp = exp0
        yp = round((x + 1)/resolution, digits) # Round to account for numerical discrepancies
    else:
        n = round((1000 - 1) * resolution) # The number of values in all other ranges
        z = round(x - (1000 * resolution - 1)) # Subtract the number of values in the first range
        r = z // n + 1          # The number of passed ranges
        yp = round((z % n)/resolution + 1, digits)
        exp = exp0 + 3 * r
    return yp * 10**exp

resolution = 10 और digits = 1 के साथ पहली श्रेणी में प्रत्येक चरण ०.१ nJ है, और फिर ०.१ µJ, ०.१mJ ......

0
Kajsa 30 अक्टूबर 2018, 21:38

आपके पास प्रत्येक आधे-खुले अंतराल में 9999 मान हैं और अंतिम, बंद अंतराल में 90 हैं, क्योंकि (उदाहरण के लिए) 10000(0.1 nJ)=1 µJ। यह रूपांतरण को आसान बनाता है:

def val(x):   # 0<=x<30,087
  r,x=divmod(x,9999)
  return (x+1)*1000**(r-3)/10

(अन्य श्रेणियों का समर्थन करने के लिए टिप्पणियों में कुछ है, लेकिन यह उत्तर देने के लिए पर्याप्त विशिष्ट नहीं है।)

1
Davis Herring 30 अक्टूबर 2018, 18:02