Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add python additional sample #1

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion C#/STPWithClass/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static void Main(string[] args)
case "show":
for (int i = 0; i < items.Count; i++)
{
Console.WriteLine($"{i}:{items[i].GetIntroTxt()}");
Console.WriteLine($"{i}:{items[i].GetIntroTxt()}");
}
break;
case "buy":
Expand Down
101 changes: 101 additions & 0 deletions Python/STP_advance/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
class Item:
def __init__(self,name,value):
self.name=name
self.value=value
self.count=0

def Buy(self):
self.count+=1

def GetAmountOfMoney(self):
return self.value*self.count

def GetIntroTxt(self):
return f"{self.name}:{self.value}円"

class Cart:
def __init__(self):
self.items=[]
self.item_names=[]

def GetSum(self):
total=0
for item in self.items:
total+=item.GetAmountOfMoney()
return total

def AddItem(self,cmds):
if not cmds[2].isdecimal():
return "3つ目には価格を入れてください"
if cmds[1] in self.item_names:
return "既にその名前のアイテムが存在します"
name=cmds[1]
value=int(cmds[2])
newItem=Item(name,value)
self.item_names.append(name)
self.items.append(newItem)
return f"{value}円の{name}を登録しました"

def CheckOut(self):
for item in self.items:
print(item.GetIntroTxt()+f"*{item.count}")
item.count=0
return f"合計金額:{self.GetSum()}円"

def Show(self):
if len(self.items)==0:
return "まだ何も登録していません"
ret=""
for i,item in enumerate(self.items):
ret+= f"{i}:{item.GetIntroTxt()}\n"
return ret

def Buy(self,cmd):
targetitem=self.SearchItem(cmd[1])
if targetitem==-1:
return "アイテムが見つかりませんでした"
targetitem.Buy()
return f"{targetitem.name}を一個購入しました"

def SearchItem(self,cmd):
for item in self.items:
if item.name==cmd:
return item
if cmd.isdecimal():
index=int(cmd)
if 0<=index<len(self.items):
return self.items[index]
else:
return -1
return -1



def print_help():
print("exit:このプログラムを終了する")
print("add [name] [value]:新たな商品nameをvalue円で登録する")
print("show:今までに登録した賞品の一覧を出力")
print("buy [name/index]:指定した商品を購入、該当しない場合は何も起こらない")
print("checkout:今まで購入した商品で会計を行い、合計金額などを出力")



mycart=Cart()
while True:
cmd=input("STP>")
cmds=cmd.split(" ")
if cmds[0]=="exit":
break
elif cmds[0]=="help":
print_help()
elif cmds[0]=="add":
print(mycart.AddItem(cmds))
elif cmds[0]=="show":
print(mycart.Show())
elif cmds[0]=="buy":
print(mycart.Buy(cmds))
elif cmds[0]=="checkout":
print(mycart.CheckOut())
else:
print("有効なコマンドを指定してください")
print("コマンド一覧はhelpで確認できます")
3 changes: 3 additions & 0 deletions Python/STP_testcasemaker/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
testcase/*
answer/*
submission*
68 changes: 68 additions & 0 deletions Python/STP_testcasemaker/how_to_make_taestcase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# テストケースの生成方法及びテスターの使用法

## 要約
- 入力は1000行
- 最初はadd,最後二つはcheckout->exit
- add,show,checkoutがそれぞれおおよそ1割、buyがおおよそ7割
- show,checkoutはそれぞれで連続はしない(show->checkout及びその逆はありうる)
- 入出力に使用される文字は英数字のみ
- テストケース生成してからテスターを使用すること
- 出力の行頭が#の時はコメントとして無視する
- 出力の形式は以下に記載

## 出力の形式
出力が必要な命令はshowとcheckoutのみである。
行頭に#を入れるとデバッグ用のメッセージとして扱われその行は無視される。
### show
```
形式:
{id}:{name} {value}yen

例:
0:apple 500yen
1:banana 300yen
2:cucumber 200yen
:
:
```

- id: addされた順番(0から)
- name: 商品の名前
- value: 価格

nameとvalueの間にスペースを入れ、商品ごとに改行するのを忘れずに。

### checkout
```
形式:
{id}:{name} {value}yen*{count}
:
:
total:{total}yen

例:
0:apple 500yen*0
1:banana 300yen*1
2:cucumber 200yen*2
:
:
total:123456yen
```

- id: addされた順番(0から)
- name: 商品の名前
- value: 価格
- total: 合計金額

showに加え、各商品の現在購入している数を出力していき、最後にその合計金額を出力する。


## コマンドの種類と生成方法
- add
- buy
- show
- checkout

1から10の乱数を生成し、1の場合add,2の場合show,3の場合checkout,4以上の場合buyを生成する。
ただし、show,checkoutについては前の行と同じ場合それ以外が選択されるまで再抽選される。同様に998行目でcheckoutが選択された際も再抽選される。
また1行目は必ずaddが生成される。
163 changes: 163 additions & 0 deletions Python/STP_testcasemaker/testcasemaker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import os
import random

class Item:
def __init__(self,name,value):
self.name=name
self.value=value
self.count=0

def Buy(self):
self.count+=1

def GetAmountOfMoney(self):
return self.value*self.count

def GetIntroTxt(self):
return f"{self.name} {self.value}yen"

class Cart:
def __len__(self):
return len(self.items)
def __init__(self):
self.items=[]
self.item_names=[]

def GetSum(self):
total=0
for item in self.items:
total+=item.GetAmountOfMoney()
return total

def AddItem(self,cmds):
if not cmds[2].isdecimal():
return "include the price in third argument"
if cmds[1] in self.item_names:
return "item with that name already exists"
name=cmds[1]
value=int(cmds[2])
newItem=Item(name,value)
self.item_names.append(name)
self.items.append(newItem)
return f"added!:{name} {value}"

def CheckOut(self):
ret=""
for i,item in enumerate(self.items):
ret+=f"{i}:{item.GetIntroTxt()}*{item.count}\n"
ret+=f"total:{self.GetSum()}yen"
for item in self.items:
item.count=0
return ret

def Show(self):
if len(self.items)==0:
return "item list is empty"
ret=""
for i,item in enumerate(self.items):
ret+= f"{i}:{item.GetIntroTxt()}\n"
return ret

def Buy(self,cmd):
targetitem=self.SearchItem(cmd[1])
if targetitem==-1:
return "item not found"
targetitem.Buy()
return f"bought one {targetitem.name}"

def SearchItem(self,cmd):
for item in self.items:
if item.name==cmd:
return item
if cmd.isdecimal():
index=int(cmd)
if 0<=index<len(self.items):
return self.items[index]
else:
return -1
return -1


item_name_box=[
"Python",
"C",
"CSharp",
"CPlusPlus",
"D",
"Swift",
"Kotlin",
"FORTRAN",
"Ruby",
"Rust",
"Go",
"Haskell",
"Java",
"JavaScript",
"Perl",
"PHP",
"Scratch",
"TypeScript"
]




def GetNewItem():
newitem=random.randrange(len(item_name_box))
number=str(cnt[newitem])
if number=="1":number=""
cnt[newitem]+=1
return item_name_box[newitem]+number

os.makedirs("./testcase",exist_ok=True)

for SEED in range(50):
random.seed(SEED)
cmd=[]
ans=[]
cnt=[1]*len(item_name_box)
first_item_num=random.randrange(len(item_name_box))
first_item=item_name_box[first_item_num]
first_item_value=str(random.randint(500,1500))
cnt[first_item_num]+=1

mycart=Cart()
mycart.AddItem([0,first_item,first_item_value])
cmd.append(f"add {first_item} {first_item_value}")
i=1
while i!=998:
rnd=random.randint(1,10)
if rnd==1:#add
item_name=GetNewItem()
item_value=str(random.randint(500,1500))
cmd.append(f"add {item_name} {item_value}")
mycart.AddItem([0,item_name,item_value])
elif rnd==2:#show
if cmd[-1]=="show":
continue
cmd.append("show")
ans.append(mycart.Show())
elif rnd==3:#checkout
if cmd[-1]=="checkout" or i==998:
continue
cmd.append("checkout")
ans.append(mycart.CheckOut())
elif 4<=rnd:#buy
buy_item=str(random.randrange(len(mycart)))
cmd.append(f"buy {buy_item}")
mycart.Buy([0,buy_item])

i+=1

cmd.append("checkout")
ans.append(mycart.CheckOut())
cmd.append("exit")


with open(f"./testcase/{SEED:04}_in.txt","w")as f:
for i in cmd:
f.write(i+["\n",""][i[-1]=="\n"])

with open(f"./testcase/{SEED:04}_out.txt","w")as f:
for i in ans:
f.write(i+["\n",""][i[-1]=="\n"])
43 changes: 43 additions & 0 deletions Python/STP_testcasemaker/tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import io
import os
import sys
os.makedirs("./answer",exist_ok=True)
judge=[]
for ans_file_num in range(10):
#入出力のポインタを取得
input_file=open(f"./testcase/{ans_file_num:04}_in.txt","r")
output_file=open(f"./answer/{ans_file_num:04}_ans.txt","w")
sys.stdin=input_file
sys.stdout=output_file
with open("submission2.py","r")as f:
exec(f.read())
input_file.close()
output_file.close()

with open(f"./answer/{ans_file_num:04}_ans.txt","r")as f1:
with open(f"./testcase/{ans_file_num:04}_out.txt","r")as f2:
ans=f1.readlines()
fans=[out[:-1] for out in ans if len(out)>1 and out[0]!="#"]
inp=f2.readlines()
finp=[out[:-1] for out in inp if len(out)>1]

sys.stdout=sys.__stdout__

print(len(fans),len(finp))

if len(fans)!=len(finp):
judge.append("WA")
continue
for fan,fin in zip(fans,finp):
if fan!=fin:
judge.append("WA")
break
else:
judge.append("AC")


sys.stdout=sys.__stdout__
print(judge)



Loading