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

[python] wartość liczby procentowo z zakresu liczb. - ćwiczenie praktyczne

VPS Starter Arubacloud
+1 głos
754 wizyt
pytanie zadane 27 maja 2020 w Python przez VBService Ekspert (251,270 p.)
edycja 23 listopada 2022 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)

1 odpowiedź

+1 głos
odpowiedź 27 maja 2020 przez adrian17 Ekspert (344,100 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 (344,100 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 Ekspert (251,270 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 (344,100 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 Ekspert (251,270 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 (344,100 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 Ekspert (251,270 p.)
edycja 23 listopada 2022 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


ciężko znaleść w necie dobry opis jak z tego korzystać a tu proszę.

Podobne pytania

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

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...