• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Wartość liczby procentowo z zakresu liczb. Ćwiczenie praktyczne. Python.

+1 głos
283 wizyt
pytanie zadane 27 maja 2020 w Python przez VBService Mędrzec (179,230 p.)
zamknięte 30 czerwca 2020 przez VBService

W oparciu o treść wpisu na forum: Proste procenty i liczby na ich podstawie  [ Matematyka, fizyka, logika ] Postanowiłem w ramach ćwiczenia z uwagi na to, że dopiero od niedawna próbuje swoich sił w nauce języka programowania python, napisać skrypt do rozwiązania problemu tam postawionego. Proszę o ewentualne uwagi, co można było zapisać lepiej, inaczej (lepsza wydajność wykonywanego kodu), co dodać itp. Z góry dziękuję.
 

Wersja oryginalna - pierwsza publikacja posta. 


from termcolor import colored # https://pypi.org/project/termcolor/
import random

def left(string,length): return string[:length] # funkcja wykorzystywana
def right(string,length): return string[-length:] # funkcja nieużywana - pozostawiona - cel edukacyjny
def mid(string,start,length): return string[start:start+length] # funkcja wykorzystywana

how_many_tries = 10
how_many_tries_count = 1
how_many_tries_count_str = ""

range_min = 0
range_max = 0
range_min_str = ""
range_max_str = ""
number_from_range = 0
number_from_range_str = ""

calculate_percent_str = ""
calculate_percent_str_left = ""
calculate_percent_str_right = ""
string_line_buff = ""

print()
while how_many_tries > 0:
      range_min = random.randint(1,99)
      range_max = random.randint(100,200)
      number_from_range = random.randint(range_min + 1,range_max -1)

      range_min_str = str(range_min)
      range_max_str = str(range_max)
      number_from_range_str = str(number_from_range)
      how_many_tries_count_str = str(how_many_tries_count)

      string_line_buff = "Próba " + colored(how_many_tries_count_str.rjust(2," "),"green",attrs=["bold"]) + ". "
      string_line_buff += "Zakres roboczy: "
      string_line_buff += colored(range_min_str.rjust(2," "),"yellow",attrs=["bold"]) + " [" + colored("0%",attrs=["bold"]) + "] - "
      string_line_buff += colored(range_max_str,"yellow",attrs=["bold"]) + " [" + colored("100%",attrs=["bold"]) + "]. "
      string_line_buff += "Liczba " + colored(number_from_range_str.ljust(3," "),"green",attrs=["bold"]) + " z ustalonego zakresu stanowi "

      calculate_percent_str = str(round((((number_from_range - range_min) / (range_max - range_min)) * 100),2))
      calculate_percent_str_left = left(calculate_percent_str,calculate_percent_str.find("."))
      calculate_percent_str_left = calculate_percent_str_left.rjust(2," ")
      calculate_percent_str_right = mid(calculate_percent_str,calculate_percent_str.find(".") + 1,2)
      calculate_percent_str_right = calculate_percent_str_right.strip()
      calculate_percent_str_right = calculate_percent_str_right.ljust(2,"0")

      string_line_buff += colored(calculate_percent_str_left + "." + calculate_percent_str_right,"magenta") + "%"
      print(string_line_buff)

      how_many_tries_count += 1
      how_many_tries -= 1

Wersja z poprawkami zasugerowanymi przez: adrian17 (Dzięki wielkie) yes


from termcolor import colored # https://pypi.org/project/termcolor/
import random

how_many_tries = 10
# range_min = 0
# range_max = 0
# number_from_range = 0
# line_buffor = ""
output_line = ""

print()
for loop in range(how_many_tries):
      range_min = random.randint(1,99)
      range_max = random.randint(100,200)
      number_from_range = random.randint(range_min + 1,range_max -1)

      percent = ((number_from_range - range_min) / (range_max - range_min)) * 100

      line_buffor = "Próba {}. Zakres roboczy: {} [{}] - {} [{}]. Liczba {} z ustalonego zakresu stanowi {}%\n"
      line_buffor = line_buffor.format(
                     colored("{:>2}".format(loop+1), "green", attrs=["bold"]),
                     colored("{:>2}".format(range_min), "yellow", attrs=["bold"]),
                     colored("0%", attrs=["bold"]),
                     colored("{:>2}".format(range_max), "yellow", attrs=["bold"]),
                     colored("100%", attrs=["bold"]),
                     colored("{:<3}".format(number_from_range), "green", attrs=["bold"]),
                     colored("{:>5.2f}".format(percent), "magenta")
                  )
      output_line += line_buffor

print(output_line)

komentarz zamknięcia: Otrzymałem odpowiedź

1 odpowiedź

+1 głos
odpowiedź 27 maja 2020 przez adrian17 Ekspert (322,420 p.)
wybrane 28 maja 2020 przez VBService
 
Najlepsza

Główna uwaga, że jest tu tak dużo zmiennych (w jakimś stopniu duplikujących tą samą informację), że to znacząco wpływa na czytelność.

Na przykład zamiast:

how_many_tries = 10
how_many_tries_count = 1

while how_many_tries > 0:
      how_many_tries_count_str = str(how_many_tries_count)

      (...)

      how_many_tries_count += 1
      how_many_tries -= 1

Można znacznie czytelniej zapisać używając zwykłej pętli z range():

for how_many_tries_count in range(10):
      how_many_tries_count_str = str(how_many_tries_count+1)
      (...)

Nie ma też powodu by "deklarować" zmienne poza pętlą, jeśli są używane tylko jako lokalna wartość w pętli.

number_from_range = random.randint(range_min + 1,range_max -1)

Tu masz chyba buga? W zakresie na przykład 5-7 zawsze wylosujesz 6 (50%), nigdy 0% i nigdy 100%.

	calculate_percent_str = str(round((((number_from_range - range_min) / (range_max - range_min)) * 100),2))
	calculate_percent_str_left = left(calculate_percent_str,calculate_percent_str.find("."))
	calculate_percent_str_right = mid(calculate_percent_str,calculate_percent_str.find(".") + 1,2)

Można cały ten kod zastąpić prostym wbudowanym formatowaniem liczby zmiennoprzecinkowej.

Zamiast pisać te same uwagi kilka razy, pokażę jak ja bym to zapisał :) Nie mówię że to jest idealne (mieszanie colored() z formatowaniem stringów jest trochę upierdliwe), ale na intuicję w taki sposób bym wygenerował takie samo wyjście.

import random

print()
for i in range(10):
	range_min = random.randint(1,99)
	range_max = random.randint(100,200)
	number_from_range = random.randint(range_min+1, range_max-1)

	percent = ((number_from_range - range_min) / (range_max - range_min)) * 100

	output = "Próba {}. Zakres roboczy: {} [{}] - {} [{}]. Liczba {} z ustalonego zakresu stanowi {}%"
	output = output.format(
		colored("{:>2}".format(i+1), "green", attrs=["bold"]),
		colored("{:>2}".format(range_min), "yellow", attrs=["bold"]),
		colored("0%", attrs=["bold"]),
		colored("{:>2}".format(range_max), "yellow", attrs=["bold"]),
		colored("100%", attrs=["bold"]),
		colored("{:<3}".format(number_from_range), "green", attrs=["bold"]),
		colored("{:>5.2f}".format(percent), "magenta")
	)

	print(output)

 

1
komentarz 27 maja 2020 przez adrian17 Ekspert (322,420 p.)
A co do wydajności... to raczej nie jest coś, czym zazwyczaj się przejmować w kodzie który w większości zajmuje się po prostu pokazaniem ładnego tekstu użytkownikowi w konsoli :) I tutaj akurat problemów raczej nie ma.
komentarz 27 maja 2020 przez VBService Mędrzec (179,230 p.)
edycja 27 maja 2020 przez VBService

Tu raczej nie ma buga, Moja wina, że może trzeba było opisać komentarzem, że
range_min to zawsze 0% a range_max 100% wink. No i jakby były losowane liczby typu double to masz wtedy np.: 6.01 1%, 6.02 2% itd. 6.99 99%. Takie przynajmniej było założenie. Tu są domyślnie losowane liczby intger, więc w tym przypadku przedział od 5-7 jest prosty do policzenia "na oko" nie trzeba do tego komputera (ani kalkulatora) laugh

komentarz 27 maja 2020 przez adrian17 Ekspert (322,420 p.)
Chyba się nie zrozumieliśmy... nie chodzi mi o liczby rzeczywiste. Chodzi mi o to, że jeśli widzę tekst "liczby losowe z zakresu 5-7", to spodziewałbym się że można wylosować 5. U Ciebie nie można.
komentarz 27 maja 2020 przez VBService Mędrzec (179,230 p.)
edycja 27 maja 2020 przez VBService

Nie ma tu "... liczby losowe z zakresu ...", tylko "zakres roboczy"
Liczby są losowane, bo są potrzebne do wykonania prób (testów) czy skrypt wykonuje prawidłowo obliczenia, to są dane testowe, w normalnych warunkach, trzeba dodać jakiegoś inputa i dać możliwość wprowadzania zakresów użytkownikowi. A po za tym
sam przyznaj, że przy liczbie z zakresu (liczby całkowite) 5,6,7 co tu jest do obliczania.
Napisz jak Ty byś taki zakres zaprogramował. Chętnie zobaczę Twoje rozwiązanie. A na koniec jakbym chciał w tym przykładzie oprogramować wszystkie możliwe kombinacje to ten skrypt mógłby się stać zbyt rozbudowany i ciężki do zrozumienia dla początkujących, którzy tu ewentualnie zaglądną do tego wpisu. To nie jest wersja "produkcyjna". Pozdrawiam. laugh.

P.S. Wystarczy zmodyfikować linie, czyli usuną to + 1 i  - 1. Zacznie losować albo 5 albo 6 albo 7 i co to zmieni: liczba w tym zakresie (3 liczb) to 5-0%, 6-50%, 7-100%. wink

komentarz 27 maja 2020 przez adrian17 Ekspert (322,420 p.)

No tak, o to mi chodziło ;)

Napiszę inaczej:

napisać skrypt do rozwiązania problemu tam postawionego

Tamten post mówił

Gdzie np. 62 odpowiada 0%, 134 odpowiada 50% itd.

Ale Twój skrypt nigdy by nie pokazał "0%", więc wyglądało to podejrzanie.

W każdym razie... to akurat największa pierdoła z punktów które napisałem ;)

komentarz 28 maja 2020 przez VBService Mędrzec (179,230 p.)
edycja 28 maja 2020 przez VBService

Wyświetla dla tego konkretnego (hipotetyczne dane, które mógłby podać użytkownik tu są symulowane przez wylosowane liczby i tak patrząc od góry "zrzutu":
58 to 0% i 170 to 100%
41 to 0% i 172 to 100% itd, jest ... wink        

 

Muszę tu nadmienić, że inne zmiany, które tu opisałeś, są jak najbardziej przydatne np.:
zamiana pętli while...  na  for i in range(how_many_triesjuż została zaadaptowana, jedna zmienna została z tego powodu usunięta yes no i perełka "palce lizać" laugh

ciężko znaleść w necie dobry opis jak z tego korzystać a tu proszę. Dzięki wielkie.
Uaktualnie posta o Twoje uwagi dla potomnych. wink

Podobne pytania

+1 głos
1 odpowiedź 324 wizyt
pytanie zadane 3 grudnia 2019 w Python przez Bartosz Paterek Początkujący (410 p.)
0 głosów
0 odpowiedzi 48 wizyt
0 głosów
2 odpowiedzi 854 wizyt
pytanie zadane 26 maja 2020 w C i C++ przez saju13013 Nowicjusz (230 p.)

88,701 zapytań

137,308 odpowiedzi

306,748 komentarzy

58,894 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...