Functional way of creating a vector of vector of &str in Rust where the separator will be an empty new line - rust

I am doing the advent of code 2022 day 11, where I have the following input as a &str:
Monkey 0:
Starting items: 52, 60, 85, 69, 75, 75
Operation: new = old * 17
Test: divisible by 13
If true: throw to monkey 6
If false: throw to monkey 7
Monkey 1:
Starting items: 96, 82, 61, 99, 82, 84, 85
Operation: new = old + 8
Test: divisible by 7
If true: throw to monkey 0
If false: throw to monkey 7
Monkey 2:
Starting items: 95, 79
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 5
If false: throw to monkey 3
how can I use the functional api of rust to get a vector of vector where the inner vector would contain the phrases of a monkey block? The separator should be the empty new line.
The output should be something like this:
[["Monkey 0:", " Starting items: 52, 60, 85, 69, 75, 75", " Operation: new = old * 17", " Test: divisible by 13", " If true: throw to monkey 6", " If false: throw to monkey 7"], [" Monkey 1:", " Starting items: 96, 82, 61, 99, 82, 84, 85", " Operation: new = old + 8", " Test: divisible by 7", " If true: throw to monkey 0", " If false: throw to monkey 7"]]
I have managed to do it in the imperative way, but I was not able to create it using the functional way (map, filter, fold, etc). I think the functional way is way more idiomatic rust

https://doc.rust-lang.org/std/primitive.str.html#method.split
let sections: Vec<Vec<&str>> = inpu
.split("\n\n")
.map(|section| -> Vec<&str> { section.lines().collect() })
.collect();

Related

Python3 Global Variable Issue

I am trying to learn about loops and conditions. Therefore I coded a generator, which randomly create lotto/lottery numbers. However I created a global variable 'valCount', which stores the generation count. But still got this error:
Bitte die Anzahl zu erzeugender Lottoscheine angeben: 2
Input is an integer number. Number = 2
Traceback (most recent call last):
File "/Volumes/HDD/Users/Stephan/PycharmProjects/LottZahlenGeneratorLoop/main.py", line 87, in
check_user_input(userCountInput)
File "/Volumes/HDD/Users/Stephan/PycharmProjects/LottZahlenGeneratorLoop/main.py", line 70, in check_user_input
outPutCount()
File "/Volumes/HDD/Users/Stephan/PycharmProjects/LottZahlenGeneratorLoop/main.py", line 55, in outPutCount
for x in range(valCount):
NameError: name 'valCount' is not defined
Correct behaviour:
User needs to input a number. This number get validated, if it is a digit or a letter. If this is a digit, the lotto/lottery numbers should be created by the count of users input. Otherwise, user is asked to enter number.
My code:
# IMPORTS
import random
from datetime import datetime
import os
# CLEAR CONSOLE
def clearConsole():
command = 'clear'
if os.name in ('nt', 'dos'): # If Machine is running on Windows, use cls
command = 'cls'
os.system(command)
# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
mainNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
superNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
mainNumbersLotto = mainNumbers
del mainNumbersLotto[49] # löscht die 49. Stelle von mainnumbers, da Lotto 6aus49 nur Zahlen von 1-49 existieren
global valCount
# countToCreate = input("Bitte geben sie die Anzahl zum generieren an.")
# FUNCTION EUROJACKPOT GENERATOR
def eurojackpotFunc():
global eurojackpotOutput
RandomMainNumbers = str(sorted(random.sample(mainNumbers, 5)))
RandomSuperNumbers = str(sorted(random.sample(superNumbers, 2)))
eurojackpotOutput = "\nEurojackpot\n5 aus 50: " + RandomMainNumbers + "\nEurozahlen: " + RandomSuperNumbers
print(eurojackpotOutput)
# FUNCTION Lotto6aus49 GENERATOR
def lottoNumbersFunc():
global lottoNumbersOutput
RandomLottoNumber = str(sorted(random.sample(mainNumbersLotto, 6)))
lottoNumbersOutput = "\nLotto6aus49\n6 aus 49: " + RandomLottoNumber
print(lottoNumbersOutput)
# FUNCTION GENERATE TEXTFILE WITH RESULT
def generateTxtFile():
f = open("Lottozahle" + "- " + dateFormat + ".txt", "+w")
f.write(eurojackpotOutput + "\n " + lottoNumbersOutput)
def check_user_input(input):
try:
# Convert it into integer
valCount = int(input)
print("Input is an integer number. Number = ", valCount)
outPutCount()
except ValueError:
try:
# Convert it into float
valCount = float(input)
print("Input is a float number. Number = ", valCount)
userCountInputFunc()
except ValueError:
print("No.. input is not a number. It's a string")
userCountInputFunc()
def userCountInputFunc():
global userCountInput
userCountInput = input("Bitte die Anzahl zu erzeugender Lottoscheine angeben: ")
#
def outPutCount():
# LOOP FOR GENERATING COUNT
global valCount
xCount = 0
for x in range(valCount):
xCount = xCount + 1
print("\n#################")
print(xCount, ". Generation")
eurojackpotFunc()
lottoNumbersFunc()
generateTxtFile()
valCount = str(valCount)
print("\nEs wurden erfolgreich " + valCount + " Lottoscheine generiert.")
userCountInputFunc()
check_user_input(userCountInput)
The error message shows NameError: name 'valCount' is not defined (within your loop), and from the looks of it, you're attempting to define it twice– within outPutCount and in the true global scope. As an aside, no matter where you use the keyword global, it will always belong to the global scope.
Anyways, this is the problem with global variables (especially ones that have no value assigned to them before run-time)– figuring out their value while letting various areas in the code mutate them is a self-induced headache worth avoiding.
Try passing the value you want into the function by way of its arguments. You can implement this entire program without the usage of a global variable.
Hope that helps, and keep learning!

Python, print colored duplicates found in 2 list

I'm 63 and just started with Python (My first steps with Udemy).
I'm Croatian so this is croatian language in program but you will understand when you run a program. I know it can be cleaner, shorter, more elegant etc, but as I mentioned before - I'm beginner.
import random
jedan = random.sample(range(1,99),15)
dva = random.sample(range(1,99),15)
def raspaljot(jedan, dva, i):
for x in jedan:
for y in dva:
if y == x:
index1 = jedan.index(x)
index1_str = str(index1)
index2 = dva.index(y)
index2_str = str(index2)
i += 1
x = str(x)
print(" Broj \033[31m" + x + "\033[0m,je dupli i nalazi se u listi jedan: na poziciji: \033[34m"
+ index1_str + "\033[0m a u listi dva na poziciji: \033[35m"+ index2_str + "\033[0m")
print()
print(jedan)
print(dva)
if i != 0:
print("\n *** Ukupno ima ", i, 'duplih brojeva. ***')
elif i == 0:
print("Nema duplih brojeva. :) ")
i = 0
raspaljot(jedan, dva,i)
What program do is finding duplicates in 2 random lists, them print duplicates in color and detecting position inside list[1] and list[2].
What I trying to do is printing list1 and list2 but showing duplicates in color.
For example:
[14, 78, 85, 31, 5, 54, 13, 46, 83, 4, 35, 41, 52, 51, 32]
[72, 40, 67, 85, 54, 76, 77, 39, 51, 36, 91, 70, 71, 38, 55]
here we have 3 duplicates (85,54,51). This above example on the console End was printed in white color, but I wanna these 3 numbers in red color in those two lines above.
Is this possible? I couldn't find a solution.
PS. Wing Pro version 7 on Fedora 33 Workstation / In WIngIde colors are only displayed in an external console and not the Debug I/O tool. :)
Simple solution would be something like this:
# Change list to string
jedan_str = str(jedan)
# Create set with numbers that need new color
num_set = {"85", "54", "51"}
# Iterate over every number and wrap it with color change
for i in num_set:
# Note that I used f-string to format string
# But you can also do this as "\033[31m" + i + "\033[0m"
jedan_str = jedan_str.replace("85", f"\033[31m{i}\033[0m")
# Print string that represent list
print(jedan_str)
Following the idea of using a set to determine which elements are in both lists (as Cv4niak proposed in his answer), I created a function to print the output as you desire. There are numerous other ways of achieving it, but I think this is a simple yet effective way.
The idea is to use the cprint() function from the termcolor package. You can install it with pip install termcolor, and then print normally all elements, except the ones that are duplicates, which will be printed using cprint(item, "red").
The "{:0>2d}" formatting in each ìtem print serves only to pad the number with zeros (so 2 will be printed as 02, for example), in order for the output of both lists to be aligned.
import random
from termcolor import cprint
def mark_duplicates(first, second):
duplicates = list(set(first).intersection(second))
if duplicates:
for list_ in [first, second]:
print("[", end="")
for item in list_:
if item in duplicates:
cprint("{:0>2d}".format(item), "red", end=",")
else:
print("{:0>2d}".format(item), end=",")
print("\b]")
else:
print("No duplicates.")
jedan = random.sample(range(1, 99), 15)
dva = random.sample(range(1, 99), 15)
mark_duplicates(jedan, dva)
With this, if there are no duplicates, the No duplicates. string will be printed. Also you can change the color with not much effort, and use other nice functionalities from termcolor package.

Python Dictionary gradebook, how to print pretty and edit

Write a program that lists all the students and their grades in the dictionary. Do not just put the whole dictionary object or list object into the print function (i.e. print(grade_book)). You must forma your output.
Here's the sample run of your program:
Student ID Grades
203942 88, 78, 83
236732 90, 78
9874 78
29746 79, 90
75893 82, 80
352418 77, 88, 84
13563 90, 89, 92
My current code looks like this
grade_book = { 203942: '88,78,83',
236732: '90,78',
9874: '78',
29746: 'emphasized text79,90',
75893: '82,80',
352418: '77,88,84',
13563: '90,89,92' }
print("Student ID, Grades")
for k,v in grade_book.items():
print(k,v)
I can't seem to get it to print pretty and I will need to
Select 1 to display grades
Select 2 to add new student grade
Select 3 to quit
Selection: 2

Is there a way to convert a list of integers to a single variable?

I'd like to convert a list of integers to a singe variable.
I tried this (found on another question):
r = len(message) -1
res = 0
for n in message:
res += n * 10 ** r
r -= 1
This does not work for me at all.
I basically need this:
message = [17, 71, 34, 83, 81]
(This can vary in length as I use a variable to change each one)
To convert into this:
new_message = 1771348381
A combination of join, map and str will do.
message = [17, 71, 34, 83, 81]
new_message = int(''.join(map(str, message)))
# 1771348381

Error when converting working code to a more object oriented structure Error: string indices must be integers Python 3

I keep running into the error: string indices must be integers when using placeholders for my script.
My program is supposed to track the growth of veggies purely on calculation. The idea is that each plant has it's own characteristics (eg carrotData) but instead of having code for each 'plantData' I replaced the code with (whichPlant and later whichPlantData) as a temporary placeholder (so that I don't need new code for each plant I have in my garden or that I want to add at a later point).
This is when I get the error in the last line (Plant is a class) marked with the ***. When I use (carrotData) instead of (whichPlantData) my script works. But as soon as I put in the temporary placeholder (whichPlantData) is breaks.
What causes this (so that I can avoid doing this in future projects) and how can I fix this?
thanks for the support!!
carrotData = {'plantID': '','plantingTime': dt(year=now.year, month=3, day=1), "dateOfPlanting": 0, "numberOfPlants": 0, "germinationTime": 7, "growthTime": 227, "flowerTime": 247, "harvestTime": 254, "liveCycles": 1, "status": 0}
potatoData = {'plantID': '','plantingTime': dt(year=now.year, month=3, day=1), "dateOfPlanting": 0, "numberOfPlants": 0, "germinationTime": 7, "growthTime": 227, "flowerTime": 247, "harvestTime": 254, "liveCycles": 1, "status": 0}
print ("imported plant datasheets")
#functions:
#if plant is added
def addPlant():
whichPlant = input("Which plant do you want to add? ")
n = int(input("How many plants do you want to add? "))
i = 0
whichPlantData = whichPlant + "Data"
if whichPlant in inventory:
while i < n:
i += 1
if whichPlant in plants:
plants[whichPlant] += 1
else:
plants[whichPlant] = 1
***Error*** whichPlant = Plant("", whichPlantData['plantingTime'], dt.now(), n, dt.now() + timedelta(days=whichPlantData['germinationTime']), dt.now() + timedelta(days=whichPlantData['growthTime']), dt.now() + timedelta(days=whichPlantData['flowerTime']),whichPlantData['harvestTime'], whichPlantData['liveCycles'], whichPlantData['status'])
Your problem seems to be with whichPlantData = whichPlant + "Data". whichPlant is a string returned by the input function. I think what you're trying to do is get a dictionary of plant information based on input from the user. Furthermore; whichPlant + "Data" seems like an attempt at making whichPlant the same as a variable name pointing towards a dictionary of plant information. Just because the string whichPlant may be equal to the variable name carrotData does not make it the same as the variable. I would suggest making a list of dictionaries full of the information about the plant then iterate over the items in that list to see if the dictionaries name key is the same as the user input.
Similar to this:
plants = [{"Name": "Carrot", 'plantID': '','plantingTime':0, "dateOfPlanting": 0, "numberOfPlants": 0, "germinationTime": 7, "growthTime": 227, "flowerTime": 247, "harvestTime": 254, "liveCycles": 1, "status": 0},
{"Name": "Potato", 'plantID': '','plantingTime': 0, "dateOfPlanting": 0, "numberOfPlants": 0, "germinationTime": 7, "growthTime": 227, "flowerTime": 247, "harvestTime": 254, "liveCycles": 1, "status": 0}]
PlantName = input("Enter a Plant: ")
for plant in plants:
if plant['Name'] == PlantName:
print("{}'s germinationTime is {}".format(PlantName, plant["germinationTime"]))
# DO SOMETHING

Resources